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

What is the use of ignoring `SIGCHLD` signal with `sigaction(2)`?

事实证明,我们可以通过将 SIGCHLD 信号指定为被其父级忽略 sigaction() 。但是,似乎 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;
}

SIGCHLD 的默认行为是丢弃信号,但 child 进程一直保持为僵尸,直到 parent 调用 wait()(或变体) 以获取其终止状态。

但是,如果您明确调用 sigaction() 并设置 SIG_IGN,这将导致它不会将 child 变成僵尸 - 当 child 退出它时立即收获。参见

获得此行为的 POSIX 方法是调用 sigactionhandler = SIG_DFL 以及包含 SA_NOCLDWAITflags。这是自 2.6 以来的 Linux。

令人困惑的是,您似乎在假设“SIGCHLD 默认被忽略”意味着信号的默认配置是 SIG_IGN

事实并非如此。默认配置为 SIG_DFL。当您将它设置为 SIG_IGN 时,您实际上是在更改它。在将其设置为 SIG_IGN 后,您可以将其还原为 SIG_DFL,再次获得原始行为。