处理多个SIGCHLD [英] Handling multiple SIGCHLD
问题描述
在运行Linux 2.6.35+的系统中,我的程序创建了许多子进程并对其进行监视.如果子进程死了,我会进行一些清理并再次产生该进程.我在进程中使用signalfd()
来获取SIGCHLD
信号. signalfd
与libevent
异步使用.
In a system running Linux 2.6.35+ my program creates many child processes and monitors them. If a child process dies I do some clean-up and spawn the process again. I use signalfd()
to get the SIGCHLD
signal in my process. signalfd
is used asynchronously using libevent
.
当将信号处理程序用于非实时信号时,当信号处理程序针对特定信号运行时,必须阻止同一信号的进一步出现,以避免进入递归处理程序.如果那时有多个信号到达,那么内核只会调用一次处理程序(当信号被解除阻塞时).
When using signal handlers for non-real time signals, while the signal handler is running for a particular signal further occurrence of the same signal has to be blocked to avoid getting into recursive handlers. If multiple signals arrive at that time then kernel invokes the handler only once (when the signal is unblocked).
使用signalfd()
时是否也具有相同的行为?由于基于signalfd
的处理不存在与正常信号处理程序的异步执行相关的典型问题,因此我认为内核可以排队进一步出现SIGCHLD
吗?
Is it the same behavior when using signalfd()
as well? Since signalfd
based handling doesn't have the typical problems associated with the asynchronous execution of the normal signal handlers I was thinking kernel can queue all the further occurrences of SIGCHLD
?
在这种情况下,谁能澄清Linux行为...
Can anyone clarify the Linux behavior in this case ...
推荐答案
在Linux上,多个子级在您读取带有signalfd()
的SIGCHLD
之前终止,将被压缩为单个SIGCHLD
.这意味着,当您读取SIGCHLD
信号时,您必须在终止的所有所有子项之后进行清理:
On Linux, multiple children terminating before you read a SIGCHLD
with signalfd()
will be compressed into a single SIGCHLD
. This means that when you read the SIGCHLD
signal, you have to clean up after all children that have terminated:
// 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()
,则终止的一个孩子不会得到处理;并且上面的循环修复了它.
I should note that I have in fact seen this signal compression when two child processed terminated at the same time. If I did only a single waitpid()
, one of the children that terminated was not handled; and the above loop fixed it.
相应的文档
- http://man7.org/linux/man-pages/man7/signal.7.html 相反,如果在当前阻塞标准信号的情况下传递了多个标准信号,则只有一个实例在排队"
- http://man7.org/linux/man-pages/man3/sigwait.3p.html 如果在调用sigwait()之前存在多个单个信号编号的挂起实例,则在实现时定义是否在成功返回后是否还有任何剩余的挂起信号那个信号号."
- http://man7.org/linux/man-pages/man7/signal.7.html "By contrast, if multiple instances of a standard signal are delivered while that signal is currently blocked, then only one instance is queued"
- http://man7.org/linux/man-pages/man3/sigwait.3p.html "If prior to the call to sigwait() there are multiple pending instances of a single signal number, it is implementation-defined whether upon successful return there are any remaining pending signals for that signal number."
这篇关于处理多个SIGCHLD的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!