本文介绍了处理多个 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.

对应文档:

这篇关于处理多个 SIGCHLD的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 02:38