处理多个SIGCHLD

在运行Linux 2.6.35 +的系统中,我的程序会创build许多subprocess并对其进行监视。 如果一个孩子的进程死了,我会做一些清理工作,并重新产生这个过程。 我使用signalfd()来获取我的进程中的SIGCHLD信号signalfd是使用libeventasynchronous使用的。

当使用信号处理程序处理非实时信号时,当信号处理程序正在运行特定信号时,必须阻止进一步发生相同的信号,以避免进入recursion处理程序。 如果当时有多个信号到达,那么内核只调用一次处理程序(当信号被解除阻塞时)。

当使用signalfd()时也是一样的行为吗? 由于基于signalfd的处理没有与正常信号处理程序的asynchronous执行相关的典型问题,我在想内核可以将所有进一步发生的SIGCHLD 排队

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

Solutions Collecting From Web of "处理多个SIGCHLD"

在Linux上,在读取signalfd()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() ,那么终止的一个孩子没有被处理。 和上面的循环固定它。

相应的文件:

实际上,无障碍的方式将是waitfd功能上,可以让你添加一个特定的PID到poll()/ epoll()。 不幸的是,它在几年前被提出时并不被Linux所接受。