2017-01-02 3 views
0

Я столкнулся с проблемой с моим приложением и spawnProcess. Если основное приложение по какой-либо причине погибает/убито, то, по-видимому, живут процессы, и я не могу связаться с ними, если я не использую терминал, чтобы убить их через их PID. Моя цель состоит в том, что если основное приложение умирает, тогда порожденные процессы также должны быть убиты.Как убить linux spawnProcess, когда основной процесс внезапно умирает?

Мой код как этот

auto appPid = spawnProcess("path/to/process"); 
scope(exit){ auto exitcode = wait(appPid); 
stderr.writeln(...);} 

И если я использую тот же подход, когда основной процесс умирает, используя wait(thisProcessID) я получаю сообщение об ошибке. Msgstr "Нет совпадений перегрузки". Любые идеи, как решить эту проблему?

+0

К тому же подходу я имею в виду «область действия (exit) {wait (thisProcessID); kill (appPID) ... ' –

+0

Вы хотите, чтобы он убил их насильственно или просто заставил основную программу остаться в живых, пока дети не закончатся? http://stackoverflow.com/a/23587108/1457000 является ответом на убийство (ту же функцию можно использовать из D .... oh poop, вы используете функции высокого уровня, поэтому вы не можете вводить этот вызов в в нужном месте. Мне нужно переосмыслить это перед публикацией в качестве ответа). Ваше ожидание не будет работать, так как spawnProcess возвращает волшебный класс, и thisProcessId просто возвращает int. ожидание ожидает класс. Но, кроме того, ждать только работает на детей, я думаю, а не на родителей ... –

+0

Привет, Адам, мне все равно, как близко, но мягко лучше. –

ответ

0

Вот код, который будет работать в Linux. Он не имеет всех функций spwnProcess stdlib, он просто показывает основные основы, но расширение его здесь не сложно, если вам нужно больше.

import core.sys.posix.unistd; 

version(linux) { 
     // this function is Linux-specific 
     import core.stdc.config; 
     import core.sys.posix.signal; 
     // we can tell the kernel to send our child process a signal 
     // when the parent dies... 
     extern(C) int prctl(int, c_ulong, c_ulong, c_ulong, c_ulong); 
     // the constant I pulled out of the C headers 
     enum PR_SET_PDEATHSIG = 1; 
} 

pid_t mySpawnProcess(string process) { 
     if(auto pid = fork()) { 
       // this branch is the parent, it can return the child pid 
       // you can: 
       // import core.sys.posix.sys.wait; 
       // waitpid(this_ret_value, &status, 0); 
       // if you want the parent to wait for the child to die 
       return pid; 
     } else { 
       // child 

       // first, tell it to terminate when the parent dies 
       prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); 

       // then, exec our process 
       char*[2] args; 
       char[255] buffer; 
       // gotta copy the string into another buffer 
       // so we zero terminate it and have a C style char**... 
       buffer[0 .. process.length] = process[]; 
       buffer[process.length] = 0; 
       args[0] = buffer.ptr; 

       // then call exec to run the new program 
       execve(args[0], args.ptr, null); 
       assert(0); // never reached 
     } 
} 

void main() { 
     mySpawnProcess("/usr/bin/cat"); 
     // parent process sleeps for one second, then exits 
     usleep(1_000_000); 
} 

Поэтому необходимо использовать функции нижнего уровня, но у Linux есть функция, которая делает то, что вам нужно.

Конечно, так как он посылает сигнал, ваш ребенок может хотеть, чтобы справиться с этим, чтобы закрыть более изящно, чем прекращение по умолчанию, но попробовать эту программу и запустить ps, пока он спит, чтобы увидеть cat работает, обратите внимание на то кошка умирает, когда родительский выход.

+0

Thaks Adam, это действительно интересно, хотя немного над моим опытом Linux сегодня. Если я понимаю ваш пример кода, используйте mySpawnedProcess для получения моего собственного pid, но у меня нет дочернего pid, чтобы я мог общаться между потоками. Однако, если у меня есть локальная переменная выше строки fork(), и после того, как fork я назначил ее родительским pid, доступны ли они для использования дочерним элементом для информирования/сигнала родителя его pid? Тогда новая вещь для меня, prctl (..), а также, насколько я понимаю, то, что я могу использовать, ... ответ на мой вопрос.Покопайтесь в свой код и протестируйте больше –

+0

'fork' возвращает * child * pid, поэтому возвращаемое значение' mySpawnProcess' является PID дочернего элемента родительскому процессу. Так что у вас уже есть это. –

Смежные вопросы