The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Как родительскому процессу не проворонить ни одного зомби? (Есть код)., !*! 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, 17:38 , 27-Июл-06 (1)
    >
    >Процесс нафоркал пятерых детей. У процесса есть обработчик сигнала SIGCHLD (сигнал о
    >том, что кто-то из детей подох) такого вида:
    >
    >А что будет, если SIGCHLD прилетит после несрабатывания бесконечного цикла, но еще
    >перед возвратом в подпрограмму, которая была прервана началом выполнения обработчика? Тоже
    >об стенку горох?
    >Блин, как же обработать гарантированно все сигналы?

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

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

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


  • Как родительскому процессу не проворонить ни одного зомби? (..., !*! michelnok, 19:59 , 27-Июл-06 (2)
    Цитата из 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 ;-|
    "




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру