使用`sigaction(2)`忽略`SIGCHLD`信号有什么用?

igo*_*gor 5 c linux signals process c99

事实证明,我们可以通过指定要由其父节点忽略的信号来防止出现僵尸进程(即父节点不wait()对其进行_exit()).但是,无论如何,它似乎默认被忽略.这怎么工作?SIGCHLDsigaction()SIGCHLD

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;
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*mar 7

默认行为SIGCHLD是丢弃信号,但子进程保留为僵尸,直到父进程调用wait()(或变量)以获得其终止状态.

但是,如果你明确地sigaction()使用处置调用SIG_IGN,那么它会导致它不会将孩子变成僵尸 - 当孩子退出时,它立即被收获.请参阅/sf/answers/502028551/

获取此行为的POSIX方法是调用sigactionwith handler = SIG_DFLflagscontains SA_NOCLDWAIT.这是2.6以来的Linux.

  • @igor是的,丢弃信号并忽略它是不同的事情。丢弃意味着信号基本上只是被丢弃,而忽略意味着信号实际上被认为已传递,但是没有执行任何处理程序或任何其他特殊操作。 (2认同)