Signals

為什麼有必要在 sigwait()‘ing 之前阻止信號?

  • January 9, 2022

在 APUE 第 12 章第 454 頁中,提到:

為了避免錯誤行為,執行緒必須阻塞它正在等待的信號……

標準中也有類似的說法:

set定義的信號在呼叫*sigwait()*時應該被阻塞;否則,行為未定義。

這些文本中討論了哪些錯誤/未定義的行為?我在標準中找不到基本原理或應用程序用法,而且我很難理解書中的解釋:

如果信號沒有被阻塞……,則打開一個計時視窗,其中一個信號可以線上程完成對sigwait.

這個答案首先將讀者帶到標準制定的歷史視角,然後將讀者的注意力引向標準的具體文本,以解釋要求的原因。

在 XPG 第 3 期中,引入sigactionsig*setsigismembersigpendingsigprocmask、 和sigsuspend,以符合 POSIX.1-1988 標準。其中,sigaction為指定信號配置提供了最全面和一致的介面;sigpendingsigprocmasksigsuspend提供了對信號進行細粒度響應的方法。

在 XPG 第 4 期(目前最古老的數字形式)中,sigaltstack引入了、 sig{hold,ignore,pause,relse,set}、 。siginterrupt最新的標準沒有說明它們來自哪裡,只是說它們都sigaltstack已經過時了,因為它們只在單執行緒程序中工作。

在 XPG 第 5 期(單一 Unix 規範版本 2)中,引入了pthread_sigmask, sigqueue, sigtimedwait, sigwaitinfo, 並sigwait與 POSIX 實時和執行緒擴展保持一致。

現在,看看標準中的其他兩個地方很重要。

系統介面一般資訊卷第一名,信號概念:

…可以“阻止”信號傳遞到執行緒。如果與阻塞信號相關聯的動作不是忽略該信號,並且如果該信號是為執行緒生成的,則該信號應保持掛起直到它被解除阻塞,當它被選擇並通過呼叫返回時被接受sigwait()函式或與之關聯的動作被設置為忽略信號。

顯然,除了可能最終忽略信號外,信號還有兩種到達程序/執行緒的方式——被解除阻塞,或被sigwait(及其兄弟姐妹,如sigtimedwaitand sigwaitinfo)接受

第二名sigaction

未指定在同一信號的程序內同時使用 sigaction() 和 sigwait() 函式的結果。

顯然,sigwait已被設想為處理信號的次要方法。

sigtimedwaitsigwaitinfo介面的基本原理中的以下文本進一步證實了這一點:

sigwait 函式為執行緒提供了一種同步機制來等待非同步生成的信號。

這來自qnx 文件,但它與所有 Unix 和類似 Unix 的發行版相關:

在呼叫 sigwait() 之前,應該阻止 set 定義的信號。如果您不阻止它們,則會出現競爭條件,即可以在發出呼叫之前傳遞信號,從而導致呼叫被阻止,您可能不希望它這樣做。

引用自:https://unix.stackexchange.com/questions/685617