URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 5603
[ Назад ]

Исходное сообщение
"Как родительскому процессу не проворонить ни одного зомби? (Есть код)."

Отправлено FastSoft , 27-Июл-06 16:48 

Процесс нафоркал пятерых детей. У процесса есть обработчик сигнала SIGCHLD (сигнал о том, что кто-то из детей подох) такого вида:

void handler(int signo) {

pid_t pid;
int stat;

pid = wait(&stat);
printf("child %d terminated", pid);
return;
}

Проблема в том, что если пять детей подохнут одновременно, то в родителю будет кинуто пять похоронок (SIGCHLD). Первая из них спровоцирует начало выполнения обработчика сигнала SIGCHLD - handler-а. Во время выполнения handler-а остальные сигналы, ни о чем не подозревая, прилетят родителю и как об стенку горох. Тогда берем и пишем такое:

void handler(int signo) {

pid_t pid;
int stat;

while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) printf("child %d terminated\n", pid);
return;
}

Типа чтобы побольше зацепить зомбаков при выполнении обработчика?
А что будет, если SIGCHLD прилетит после несрабатывания бесконечного цикла, но еще перед возвратом в подпрограмму, которая была прервана началом выполнения обработчика? Тоже об стенку горох?
Блин, как же обработать гарантированно все сигналы?


Содержание

Сообщения в этом обсуждении
"Как родительскому процессу не проворонить ни одного зомби? (..."
Отправлено NuINu , 27-Июл-06 17:38 
>
>Процесс нафоркал пятерых детей. У процесса есть обработчик сигнала SIGCHLD (сигнал о
>том, что кто-то из детей подох) такого вида:
>
>А что будет, если SIGCHLD прилетит после несрабатывания бесконечного цикла, но еще
>перед возвратом в подпрограмму, которая была прервана началом выполнения обработчика? Тоже
>об стенку горох?
>Блин, как же обработать гарантированно все сигналы?

Ты уж выбери что нибудь одно либо сигналы обработать, либо зомби убить.

Что б сигналы обработать нужно как можно меньши в обработчике сидеть, и менять переменные с типом: sigaction. А ты там printf вызываешь ;-)))

А что бы зомби все убить, можно в конце программы запустить цикл с waitpid.
Хотя в принципе их и без тебя потом должны убить.



"Как родительскому процессу не проворонить ни одного зомби? (..."
Отправлено michelnok , 27-Июл-06 19:59 
Цитата из RU.UNIX.PROG FAQ:
"
>Q: Дочерние процессы становятся зомби, несмотря на то, что есть
>   обработчик сигнала SIGCHLD, вызывающий wait/waitpid/wait3/wait4.
>   Что не так?

A:

Сигнал SIGCHLD, как и все остальные сигналы основной (не realtime) группы,
может накапливаться так, что обработчик вызывается только один раз
независимо от того, сколько за это время сигнал был послан. В ядре в этом
случае просто ставится флажок, что надо вызвать обработчик; этот флажок
снимается при вызове обработчика. Поэтому на каждый вызов SIGCHLD надо
предполагать, что успело завершиться несколько процессов. Поэтому код
обработчика должен содержать цикл "пока еще есть завершившиеся процессы",
например:

    for(;;) {
        pid = waitpid( -1, &istatus, WNOHANG );
        if( pid == -1 && errno == EINTR )  continue;
        if( pid <= 0 )  break;
        <<учесть этот pid>>
    }

В примере в Unix Programming FAQ записан одиночный if, это неправильно.

Ну и проверьте, что обработчик SIGCHLD не заблокирован и действительно
вызывается, а то мало ли чего вы там накрутили в sigaction и sigprocmask ;-|
"