【问题标题】:Signal queuing in CC中的信号队列
【发布时间】:2011-07-14 05:06:59
【问题描述】:

我在 Linux 下有一个简单的程序,它在一个循环中向其子进程发送 SIGUSR1 信号。但是当我发送例如有时会发生 10 个信号,表明孩子只收到了其中的 3 个。最后发送的信号始终是 SIGUSR2,并且每次都会收到。

信号是否在排队,或者当进程没有处理前一个信号时,它只是被覆盖了?有没有办法可以在队列中发送信号?

【问题讨论】:

    标签: c linux queue signals


    【解决方案1】:

    您的问题可能是 SIGUSR2 是一个立即传递的信号,而其他信号被阻塞或排队(处于待处理状态)。

    查看待处理信号的方法如下:http://www.gnu.org/s/libc/manual/html_node/Checking-for-Pending-Signals.html

    【讨论】:

      【解决方案2】:

      会发生以下情况:

      1. 接收到的第一个信号,即 SIGUSR1,处理程序被调用并正在运行
      2. 收到第二个信号,因为来自 nr1 的处理程序仍在运行,所以信号 nr2 处于挂起状态并被阻塞。
      3. 收到第三个信号,因为来自 nr1 的处理程序仍在运行,所以信号 3 被丢弃。
      4. 丢弃与信号 nr1 相同类型的第四、第五...等信号。

      一旦信号处理程序处理完信号 nr1,它将处理信号 nr2,然后信号处理程序将处理 SIGUSR2。

      基本上,相同类型的待处理信号不会排队,而是被丢弃。不,没有简单的方法可以以这种方式“突发”发送信号。人们总是假设可能有几个信号被丢弃,并试图让处理程序完成清理工作并找出要做什么(例如收割孩子,如果所有孩子同时死亡)。

      【讨论】:

      • 非常感谢,这就是问题所在。所以我的解决方案是,在子进程中每次收到 SIGUSR1 后,我都会用 SIGUSR2 回答,而父进程在收到子进程的 SIGUSR2 确认之前不会发送另一个 SIGUSR1。它似乎工作!再次感谢:)
      【解决方案3】:

      如果发送了多个相同类型的信号但未处理,则它们不会排队。说程序屏蔽SIGUSR1,调用kill(getpid(), SIGUSR1) 10 次并取消屏蔽SIGUSR1。它只会收到一次SIGUSR1

      【讨论】:

        【解决方案4】:

        因此,只有在 struct sigaction sa_flags 字段使用标志 SA_NODEFER 并且从不阻塞信号时,才可以使用 SIGIO 对多个文件进行同时 I/O。

        因此,可以从信号处理程序内部获得中断,并为每个正在处理的单独信号创建新线程。这变得复杂了 :) 所以难怪为什么似乎没有人使用 SIGIO。

        【讨论】:

          猜你喜欢
          • 2010-10-15
          • 1970-01-01
          • 1970-01-01
          • 2021-03-01
          • 1970-01-01
          • 2013-07-05
          • 2017-04-18
          • 2012-10-18
          • 1970-01-01
          相关资源
          最近更新 更多