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

时间:2016-11-15 03:02:23

标签: c linux process signals c99

事实证明,我们可以通过指定wait()信号来防止出现僵尸进程(即父母不会_exit()对其进行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;
}

2 个答案:

答案 0 :(得分:6)

SIGCHLD的默认行为是丢弃信号,但子进程保留为僵尸,直到父进程调用wait()(或变体)才能获得终止状态。

但是,如果你明确地使用处置sigaction()来调用SIG_IGN,这会导致它不会将孩子变成僵尸 - 当孩子退出时会立即收到它。见https://stackoverflow.com/a/7171836/1491895

获取此行为的POSIX方法是使用sigactionhandler = SIG_DFL调用包含flags的{​​{1}}。这是2.6以来的Linux。

答案 1 :(得分:0)

困惑是您似乎在假设“ Auth.auth().createUser(withEmail: email, password: password) { (result, error) in if error != nil { //Create account } else { KeychainWrapper.standard.set((result?.user.uid)!, forKey: "KEY_UID") } } 被默认忽略”意味着信号的默认设置为SIGCHLD

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