【问题标题】: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 个响应?您还可以包括超时延迟,以防其中一个孩子被挂断。
  • 标志需要使用共享内存。不幸的是,我只需要使用信号来实现这一点。

标签: c unix signals ipc


【解决方案1】:

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

  1. 管道
  2. 共享内存
  3. 套接字
  4. 文件

【讨论】:

    【解决方案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() 应该在一个循环中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多