2011-03-12 57 views
9

我有一個簡單的程序在Linux下發送SIGUSR1信號給它的子進程的一個循環。但是當我發送例如有時會發生10個信號,表明孩子只收到3個信號。最後發送的信號總是SIGUSR2,並且每次都收到。信號在C排隊

信號排隊,或者當進程沒有處理前一個時,它被簡單地覆蓋?有什麼方法可以發送隊列中的信號?

回答

12

什麼情況如下:收到

  1. 第一信號,即SIGUSR1,處理程序被調用並收到運行
  2. 第二信號,由於來自nr1的處理程序仍在運行,所以信號nr2會掛起並被阻塞。
  3. 收到第三個信號,由於nr1的處理程序仍在運行,信號3被丟棄。
  4. 與信號nr1相同類型的第四,第五...等信號被丟棄。

一旦信號處理程序完成信號nr1,它將處理信號nr2,然後信號處理程序將處理SIGUSR2。

基本上,相同類型的未決信號不會排隊,而是被丟棄。不,沒有簡單的方法可以通過這種方式「發送」發送信號。人們總是會假設可能會丟棄幾個信號,並試圖讓處理程序執行清理工作並找出要做的事情(例如,如果所有兒童都在同一時間死亡,則收穫兒童)。

+1

非常感謝,那就是問題所在。所以我的解決方案是,在每次接收到SIGUSR1子進程後,我回答SIGUSR2,並且父進程在從子進程接收到SIGUSR2確認之前不會發送另一個SIGUSR1。它似乎工作!再次感謝:) – 2011-03-12 22:52:46

6

如果多個相同類型的信號被髮送並且未被處理,它們不會被排隊。說程序掩碼SIGUSR1,調用kill(getpid(), SIGUSR1) 10次,並揭露SIGUSR1。它只會收到SIGUSR1一次。

1

因此,只有在結構信號sa_flags字段使用標誌SA_NODEFER並且從不阻止信號的情況下,SIGIO似乎可以同時對多個文件執行I/O操作。

那麼,可以從信號處理程序中獲取中斷,併爲每個正在處理的單個信號創建新的線程。這變得複雜:)所以難怪爲什麼沒有人似乎使用SIGIO。