Linux 处理多个 SIGCHLD

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8398298/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 03:31:05  来源:igfitidea点击:

Handling multiple SIGCHLD

linuxlinux-kernelsignals

提问by Manohar

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 SIGCHLDsignal in my process. signalfdis used asynchronously using libevent.

在运行 Linux 2.6.35+ 的系统中,我的程序创建了许多子进程并监视它们。如果子进程死亡,我会进行一些清理并再次生成该进程。我用来在我的过程中signalfd()获取SIGCHLD信号。signalfd使用异步使用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).

当对非实时信号使用信号处理程序时,当信号处理程序正在为特定信号运行时,必须阻止相同信号的进一步发生以避免进入递归处理程序。如果此时有多个信号到达,则内核仅调用一次处理程序(当信号未阻塞时)。

Is it the same behavior when using signalfd()as well? Since signalfdbased handling doesn't have the typical problems associated with the asynchronous execution of the normal signal handlers I was thinking kernel can queueall the further occurrences of SIGCHLD?

使用时是否也有相同的行为signalfd()?由于signalfd基于处理没有与正常的信号处理我想内核可以异步执行相关的典型问题,排队的所有的再次发生SIGCHLD

Can anyone clarify the Linux behavior in this case ...

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

采纳答案by Ambroz Bizjak

On Linux, multiple children terminating before you read a SIGCHLDwith signalfd()will be compressed into a single SIGCHLD. This means that when you read the SIGCHLDsignal, you have to clean up after allchildren that have terminated:

在 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
}

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.

我应该注意到,当两个子进程同时终止时,我实际上已经看到了这种信号压缩。如果我只做了一个waitpid(),终止的孩子之一没有被处理;上面的循环修复了它。

Corresponding documentation:

对应文档:

回答by Pavel ?imerda

Actually the hassle-free way would be the waitfdfunctionally that would allow you to add a specific pid to poll()/epoll(). Unfortunately, it wasn't accepted to Linux years ago when it was proposed.

实际上,最简单的方法是在waitfd功能上允许您向 poll()/epoll() 添加特定的 pid。不幸的是,几年前它被提出时并没有被 Linux 接受。