深入理解linux核心——訊號

訊號是很短的訊息,可以被髮送到一個程序或一組程序。傳送給程序的唯一訊號通常是一個數。

使用訊號的兩個主要的目的是:

讓程序知道已經發生了一個特定的事件。

強迫程序執行它自己程式碼中的訊號處理程式。

訊號的一個重要特點是它們可以隨時被髮送給狀態經常不可預知的程序。傳送給非執行程序的資訊號必須由核心保護,直到程序恢復執行。阻塞一個訊號要求訊號的傳遞拖延,直到隨後解除阻塞,這使得訊號產生一段時間之後才能對其傳遞這一問題變得更加嚴重。

因此,核心區分資訊傳遞的兩個不同階段:

訊號產生

核心更新目標程序的資料結表示一個新訊號已被髮送。

訊號傳遞

核心強迫目標程序透過以下方式對訊號作出反應:或改變目標程序的執行狀態,或開始執行一個特定的訊號處理程式,或兩者都是。

深入理解linux核心——訊號

每個所產生的訊號至多被傳遞一次。訊號是可以消費資源:一旦它們已傳遞出去,程序描述符中有關這個訊號的所有資訊都被取消。

已經產生但還沒有傳遞的訊號稱為掛起訊號(pending singal)。任何時候,一個程序僅存在給定型別的一個掛起訊號,同一程序同種型別的其他資訊不被排隊,只被簡單地丟棄。但是,實時訊號是不同的:同種型別的掛起訊號可以有好幾個。

深入理解linux核心——訊號

程序描述符的signal欄位指向訊號描述符(signal descriptor)—— 一個single_struct型別的結構,用來跟蹤共享掛起訊號。

除了訊號描述符以外, 每個程序還引用一個訊號處理程式描述符(signad handler descriplor),它是一個sighand_strust型別的結構,用來描述每個訊號必須怎樣被執行緒組處理。

深入理解linux核心——訊號

很多核心函式都會產生訊號:它們完成訊號處理第一步的工作,即根據需要更新一個或多個程序的描述符。它們不直接執行第二步的訊號民傳遞操作,而是可能根據訊號的型別和目標程序的狀態喚醒一些程序,並促使這些程序接收訊號。