linux - 处理多个 SIGCHLD

标签 linux linux-kernel signals

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

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

使用 signalfd() 时是否也有同样的行为?由于基于 signalfd 的处理没有与异步执行普通信号处理程序相关的典型问题,我认为内核可以排队 SIGCHLD 的所有进一步出现

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

最佳答案

在 Linux 上,在您使用 signalfd() 读取 SIGCHLD 之前终止的多个子级将被压缩为单个 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(),则终止的子进程之一不会得到处理;上面的循环修复了它。

对应文档:

关于linux - 处理多个 SIGCHLD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8398298/

相关文章:

linux - 如何使用 QEMU 调试 Linux 内核模块?

c - "CPU dies"(与硬件无关)是什么意思?

c - pthreads 和信号处理 C 提前结束

Go信号处理

linux - 谁在写我的文件或者为什么 lsof 没有显示作者但读者显示

php - 无法连接服务器以从本地系统访问数据库

linux - 管理来自自定义硬件的中断

python - 在python中,调用后是否有可能发生异常,但其后的try block 为 "before"?

c - 从 Bash 终端重新启动 C 程序

linux - 使用打印两个不同的文件字段