如何在不丢失信号的情况下将信号从多个子进程发送到主进程?

Posted

技术标签:

【中文标题】如何在不丢失信号的情况下将信号从多个子进程发送到主进程?【英文标题】:How to send signals from multiple children to main process without loosing signals on the way? 【发布时间】:2014-01-03 22:36:48 【问题描述】:

Full program

总结:主进程分叉 3 个子进程,向每个进程发送信号,然后等待。反过来,当每个孩子收到信号时,它会被重定向到 child() 函数,向主进程发送信号(并调用father() 函数),然后等待。如果主进程收到 3 个信号,它将终止子进程并结束程序。

问题是主进程只接收一次信号。我怀疑在执行father() 函数时其他2 个信号丢失了,或者我只是遗漏了一些东西

有没有办法知道某些信号是否丢失?那我该如何避免这种情况呢?

【问题讨论】:

如何设置一个标志以在终止之前查找 x 个响应?您还可以包括超时延迟,以防其中一个孩子被挂断。 标志需要使用共享内存。不幸的是,我只需要使用信号来实现这一点。 【参考方案1】:

信号不可靠,如果您需要确保收到消息,应避免使用。更可靠的方法是使用

    管道 共享内存 套接字 文件

【讨论】:

【参考方案2】:

在信号处理程序中使用pause() 不允许再次传递信号。在输入信号处理程序之前,信号要么被屏蔽,要么被重置为其默认操作(大多数实现都是前者)。

另一个问题是来自kill() 的信号可能会与相同信号编号的另一个实例合并。如果接收进程没有足够快地运行,就会发生这种情况:如果一个新信号进入,而另一个信号已经在等待相同的信号编号,则新信号可能会被丢弃。您可以通过为每个发送者使用不同的信号编号或使用sigqueue() 和使用sigaction() 安装的处理程序和SA_SIGINFOsa_flags 中设置来避免这种情况。这些都不是无限扩展的。

避免使用过时的函数pause()signal() 是明智的。最好改用sigsuspend()sigaction()

您可以使用sigprocmask()pthread_sigmask() 临时阻止信号。这将让您避免竞争条件,例如在安装处理程序之前传入的信号。

sigwait() 函数可让您在程序的主要流程中处理信号。

按照惯例,正常终止是使用SIGTERM,而不是SIGQUIT。请注意,SIGQUIT 的默认操作包括核心转储或类似操作。

【讨论】:

我使用了sigaction()sigqueue(),就像你为 SIGUSR1 建议的那样,但主进程仍然只得到 1 个信号。 Here is a link to the updated code。我使用了来自here 的示例。你能指出我做错了什么吗? 我也尝试使用 sigsuspend() 而不是 pause()。没有帮助。 在信号处理程序中使用pause()sigsuspend() 是错误的。相反,main() 中的 pause() 应该在一个循环中。

以上是关于如何在不丢失信号的情况下将信号从多个子进程发送到主进程?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不丢失 css 的情况下将模板从桌面发送到移动设备

如何在不声明 32 个插槽的情况下将 32 个按钮的 press() 信号连接到单个函数?

fork 和 signal:如何将信号从父进程发送到特定的子进程

如何在不丢失导航栏的情况下将子视图添加到 UINavigation 控制器?

如何在不使用 C++/C 中的阻塞函数的情况下将值从线程返回到主函数

如何在不破坏SQL逻辑的情况下将JOINS转换为子查询