Выходит ли сигнал KILL из процесса сразу? - PullRequest
11 голосов
/ 30 декабря 2011

Я работаю над кодом сервера, который использует fork() и exec для создания дочерних процессов. PID ребенка регистрируется при успешном выполнении fork() и очищается при получении сигнала CHILD.

Если сервер должен остановиться, все программы будут убиты, в конце концов с сигналом KILL. Теперь это работает посредством итерации всех зарегистрированных PID и ожидания обработчика сигнала CHILD для удаления PID. Это не удастся, если дочерняя программа не завершится правильно. Поэтому я хочу использовать kill в сочетании с waitpid, чтобы обеспечить очистку списка PID, ведение журнала и выполнение других действий в противном случае.

Рассмотрим следующий пример кода:

kill(pid, SIGKILL);
waitpid(pid, NULL, WNOHANG);

Выдержка из waitpid(2):

waitpid (): в случае успеха возвращает идентификатор процесса ребенка, состояние которого изменилось; если был указан WNOHANG и один или несколько дочерних объектов (ren) указанные pid существуют, но еще не изменили состояние, затем возвращается 0. При ошибке возвращается -1.

Всегда ли процесс, заданный pid, завершался до того, как включилась следующая функция? Будет ли waitpid всегда возвращать -1 в указанном выше случае?

Ответы [ 2 ]

9 голосов
/ 30 декабря 2011

Всегда ли завершается процесс, заданный pid до запуска следующей функции?

На это нет никаких гарантий. На мультипроцессоре ваш процесс может быть на CPU 0, тогда как очистка в ядре для уничтоженного процесса происходит на CPU 1. Это классическое условие гонки. Даже на одноядерных процессорах нет никаких гарантий для этого.

Будет ли waitpid всегда возвращать -1 в указанном выше случае?

Поскольку это состояние гонки, в большинстве случаев, возможно, так и будет. Но нет гарантии.


Поскольку вас не интересует статус, этот полукод может быть более подходящим для вашего случая:

// kill all childs
foreach(pid from pidlist)
    kill(pid, SIGKILL);

// gather results - remove zombies
while( not_empty(pidlist) )
    pid = waitpid(-1, NULL, WNOHANG);
    if( pid > 0 )
        remove_list_item(pidlist, pid);
    else if( pid == 0 )
        sleep(1);
    else
        break;
4 голосов
/ 30 декабря 2011

Обработчик сигнала KILL будет запущен во время процессорного времени остановленных процессов.Это потенциально намного позже, чем ваш waitpid вызов, особенно в загруженной системе, поэтому waitpid может очень хорошо вернуть 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...