2016-11-15 10 views
3

Оказывается, мы можем предотвратить появление процесса зомби (т. Е. Тот, у которого родительский не wait() для него до _exit()), указав SIGCHLD сигнал, который должен быть проигнорирован его родителем sigaction(). Однако, по-видимому, SIGCHLD по-прежнему игнорируется. Почему это работает?Каково использование игнорирования сигнала SIGCHLD с помощью `sigaction (2)`?

int main (void) { 
    struct sigaction sa; 
    sa.sa_handler = SIG_IGN; //handle signal by ignoring 
    sigemptyset(&sa.sa_mask); 
    sa.sa_flags = 0; 
    if (sigaction(SIGCHLD, &sa, 0) == -1) { 
     perror(0); 
     exit(1); 
    } 
    int pid = fork(); 
    if (pid == 0) { //child process 
     _exit(0); 
    } 
    do_something(); //parent process 
    return 0; 
} 

ответ

4

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

Но если вы явно вызываете sigaction() с распоряжением SIG_IGN, это заставляет его не превращать ребенка в зомби - когда ребенок выйдет, он будет получен немедленно. См https://stackoverflow.com/a/7171836/1491895

Путь POSIX, чтобы получить такое поведение путем вызова sigaction с handler = SIG_DFL и flags содержащий SA_NOCLDWAIT. Это в Linux с 2.6.

+0

Означает ли это, что отказ от сигнала и игнорирование сигнала - это два разных поведения? – igor

+0

Что особенно важно, игнорируя это явно, вызывая 'sigaction()'. Он не изменяет способ обработки сигнала в вашем процессе, но он изменяет то, что происходит с процессом, который выходит. – Barmar

+1

@igor Да, отбрасывая сигнал и игнорируя это разные вещи. Отбрасывание означает, что сигнал в основном просто выброшен, в то время как игнорирование означает, что он фактически считается доставленным, но обработчик или любые другие специальные действия не выполняются. – twalberg