在运行Linux 2.6.35+的系统中,我的程序创建了许多子进程并对其进行监视。如果子进程死了,我会进行一些清理并再次产生该进程。我signalfd()经常SIGCHLD在过程中获取信号。signalfd与异步使用libevent。
signalfd()
SIGCHLD
signalfd
libevent
当将信号处理程序用于非实时信号时,当信号处理程序针对特定信号运行时,必须阻止同一信号的进一步出现,以避免进入递归处理程序。如果此时有多个信号到达,则内核仅调用一次处理程序(当信号被解除阻塞时)。
使用时是否具有相同的行为signalfd()?由于signalfd基于处理没有与正常执行信号处理程序的异步执行相关的典型问题,所以我认为内核可以将所有进一步出现的事件排入 队列SIGCHLD。
任何人都可以在这种情况下阐明Linux行为吗?
在Linux上,在阅读SIGCHLDwith 之前终止的多个子代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(),那么终止的孩子之一将不会得到处理。并且上面的循环修复了它。
waitpid()
相应的文档: