在运行 Linux 2.6.35+ 的系统中,我的程序创建许多子进程并监视它们。如果子进程死亡,我会进行一些清理并再次生成该进程。我用signalfd()
得到SIGCHLD
我的进程中发出信号。signalfd
异步使用libevent
.
当对非实时信号使用信号处理程序时,当信号处理程序针对特定信号运行时,必须阻止同一信号的进一步出现,以避免进入递归处理程序。如果此时有多个信号到达,则内核仅调用处理程序一次(当信号未被阻止时)。
使用时是否有相同的行为signalfd()
还有?自从signalfd
基于处理不存在与正常信号处理程序的异步执行相关的典型问题,我认为内核可以queue所有进一步发生的SIGCHLD
?
任何人都可以澄清Linux在这种情况下的行为......
在 Linux 上,多个子进程在您读取之前终止SIGCHLD
with signalfd()
将被压缩成一个SIGCHLD
。这意味着当您阅读SIGCHLD
信号,之后你必须清理all已终止的孩子:
// 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()
,其中一个被终止的孩子没有得到处理;上面的循环修复了它。
对应文档:
-
http://man7.org/linux/man-pages/man7/signal.7.html “相比之下,如果标准信号的多个实例在该信号当前被阻止时被传递,则只有一个实例排队”
-
http://man7.org/linux/man-pages/man3/sigwait.3p.html “如果在调用 sigwait() 之前存在单个信号号的多个挂起实例,则在成功返回后是否存在该信号号的任何剩余挂起信号是实现定义的。”
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)