处理多个 SIGCHLD
- 2024-10-28 08:37:00
- admin 原创
- 56
问题描述:
在运行 Linux 2.6.35+ 的系统中,我的程序会创建许多子进程并监视它们。如果子进程死亡,我会进行一些清理并再次生成该进程。我使用在我的进程中signalfd()
获取SIGCHLD
信号。signalfd
使用 异步使用libevent
。
当使用信号处理程序处理非实时信号时,当信号处理程序正在为特定信号运行时,必须阻止同一信号的进一步出现,以避免陷入递归处理程序。如果当时有多个信号到达,则内核只会调用一次处理程序(当信号被解除阻止时)。
使用时是否也有同样的行为signalfd()
?由于signalfd
基于处理没有与正常信号处理程序的异步执行相关的典型问题,我认为内核可以将所有进一步的出现排队SIGCHLD
?
有人能澄清这种情况下 Linux 的行为吗......
解决方案 1:
SIGCHLD
在 Linux 上,在读取with之前终止的多个子进程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()
,则其中一个终止的子进程不会被处理;上面的循环修复了这个问题。
相应文档:
http://man7.org/linux/man-pages/man7/signal.7.html “相比之下,如果在标准信号当前被阻止的情况下传递了多个实例,则只有一个实例会排队”
http://man7.org/linux/man-pages/man3/sigwait.3p.html “如果在调用 sigwait() 之前,单个信号编号有多个待处理实例,则成功返回后是否有该信号编号的剩余待处理信号由实现定义。”
解决方案 2:
实际上最省事的方法是waitfd
功能上允许您将特定 pid 添加到 poll()/epoll()。不幸的是,几年前提出时它并未被 Linux 接受。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件