无法接收所有SIGCHLD

时间:2018-02-12 15:52:57

标签: c linux unix operating-system

在下面的代码中,我期待的是控制台打印十h.LineStyle='none';。通过将SIGCHLD caught设置为sa_flags并使用SA_SIGINFO代替sa_sigaction,我已经排队了SIGCHLD。但是,似乎有些SIGCHLD丢失了。为什么呢?

我认为sa_handler可能会被fork()打断,因此我使用SIGCHLD重新启动SA_RESTART。我在不同的计算机上运行相同的代码。在我的MacBook上,它显示fork()。在另一台Linux计算机上,打印的[1] 24481 illegal hardware instruction不到10个。

SIGCHLD caught

1 个答案:

答案 0 :(得分:1)

SIGCHLD是一个标准信号,这意味着它的多次出现会折叠成一个。 Linux内核为标准信号维护一个位集,每个信号一位,并支持排队一个相关的siginfo_t

修正:

void catch(int signo, siginfo_t*, void*) {
    int status;
    pid_t pid;
    if(signo == SIGCHLD) {
        while((pid = waitpid(-1, &status, WNOHANG)) > 0)
            printf("child %u terminated.\n", (unsigned)pid);
    }
}

另请注意,除非使用SA_NODEFER标志,否则您无需显式阻止您处理的信号,因为它会自动阻止您。

而且,迂腐地说,只有有限数量的异步信号安全功能(见man signal-safety)可用于信号处理程序,printf不是其中之一。