Linux學習系列-信號

信號的定義和分類

信號是軟件中斷,提供了典型的異步機制。每個信號有一個編號,信號分爲兩類:非實時信號和實時信號。0-31編號屬於非實時信號;31-63編號屬於實時信號。爲什麼會分爲這兩類信號呢?這個主要是因爲歷史原因,首先實現的是非實時信號,非實時信號也成爲不可靠信號,是因爲其實現機制導致這類信號可能會丟失;而實時信號,由於存在排隊機制,所以不會丟失。關於這點會在信號的處理過程圖示中詳細闡述。

信號的來源

信號事件的發生有兩個來源:硬件來源(比如我們按下了鍵盤或者其它硬件故障);軟件來源,最常用發送信號的系統函數是kill, raise, alarm和setitimer以及sigqueue函數,軟件來源還包括一些非法運算等操作。

信號的處理時機

每個信號都可以被關聯1個信號處理函數,如果沒有關聯,其處理動作是系統默認的,大部分都是動作都是忽略,具體每個信號的默認處理動作可以谷歌查詢。在目標進程執行過程中,會檢測是否有信號等待處理(每次從系統空間返回到用戶空間時都做這樣的檢查),如果有,則調用信號處理函數。

信號的狀態

實際執行信號的處理動作稱爲信號遞達,信號從產生到遞達之間的狀態成爲未決。進程既可以忽略信號,也可以阻塞信號。阻塞的意思是信號不會被遞達,而忽略是信號遞達之後的一個可選動作。信號在內核中的表示包括兩個標記位:阻塞標記位和未決標記位以及信號處理函數的指針。

信號的處理過程

  1. 如果存在未決信號等待處理且該信號沒有被進程阻塞,則在運行相應的信號處理函數前,進程會把信號在未決信號鏈中佔有的結構卸掉。是否將信號從進程未決信號集中刪除對於實時與非實時信號是不同的。
  2. 對於非實時信號來說,由於在未決信號信息鏈中最多隻佔用一個sigqueue結構,因此該結構被釋放後,應該把信號在進程未決信號集中刪除(信號註銷完畢)。
  3. 對於實時信號來說,可能在未決信號信息鏈中佔用多個sigqueue結構,因此應該針對佔用sigqueue結構的數目區別對待:如果只佔用一個sigqueue結構(進程只收到該信號一次),則應該把信號在進程的未決信號集中刪除(信號註銷完畢)。否則,不應該在進程的未決信號集中刪除該信號(信號註銷完畢)。

下圖就是我理解的信號處理過程:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章