处理多个SIGCHLD

时间:2011-12-06 10:22:13

标签: linux linux-kernel signals

在运行Linux 2.6.35+的系统中,我的程序会创建许多子进程并监视它们。如果子进程死亡,我会进行一些清理并再次生成进程。我使用signalfd()在我的流程中获取SIGCHLD信号。使用signalfd异步使用libevent

当将信号处理程序用于非实时信号时,当信号处理程序针对特定信号运行时,必须阻止进一步发生相同的信号以避免进入递归处理程序。如果此时多个信号到达,则内核仅调用一次处理程序(当信号被解除阻塞时)。

使用signalfd()时是否也是一样的行为?由于基于signalfd的处理没有与正常信号处理程序的异步执行相关的典型问题,我认为内核可以排队 SIGCHLD的所有其他事件?

在这种情况下,任何人都可以澄清Linux的行为......

2 个答案:

答案 0 :(得分:21)

在Linux上,在您使用SIGCHLD阅读signalfd()之前终止的多个孩子将被压缩为单个SIGCHLD。这意味着当您阅读SIGCHLD信号时,您必须在已终止的所有子项后进行清理:

// Do this after you've read() a SIGCHLD from the signalfd file descriptor:
while (1) {
    int status;
    pid_t pid = waitpid(-1, &status, WNOHANG);
    if (pid <= 0) {
        break;
    }
    // something happened with child 'pid', do something about it...
    // Details are in 'status', see waitpid() manpage
}

我应该注意到,当两个子进程同时终止时,我实际上看到了这种信号压缩。如果我只做了一个waitpid(),其中一个终止的孩子没有被处理;并且上面的循环修复了它。

相应文件:

答案 1 :(得分:0)

实际上,无障碍的方式是waitfd功能,允许您向poll()/ epoll()添加特定的pid。不幸的是,几年前它被提议用于Linux。