在运行Linux 2.6.35+的系统中,我的程序创建许多子进程并监视它们。如果一个子进程死了,我会做一些清理工作,然后再进行一次。我使用signalfd()在我的过程中获取SIGCHLD信号。signalfd是使用libevent异步使用的。
当对非实时信号使用信号处理程序时,当信号处理程序对特定信号运行时,必须阻止同一信号的进一步出现,以避免进入递归处理程序。如果此时到达多个信号,那么内核只调用处理程序一次(当信号解除阻塞时)。
在使用signalfd()时,这也是相同的行为吗?由于基于signalfd的处理不存在与正常信号处理程序异步执行相关的典型问题,我认为内核可以对所有进一步发生的SIGCHLD进行队列处理吗?
有人能澄清Linux在这种情况下的行为吗..。
发布于 2011-12-06 10:37:00
在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(),终止的子程序之一就不会被处理;上面的循环修复了它。
相应文件:
。
发布于 2013-10-23 14:45:37
实际上,无麻烦的方式将是waitfd功能,它允许您为轮询()/epoll()添加一个特定的pid。不幸的是,它在几年前被Linux提出的时候没有被接受。
https://stackoverflow.com/questions/8398298
复制相似问题