信號生命週期

  1. 信號誕生
  2. 信號在目標程序中註冊
  3. 信號在目標程序中註銷
  4. 信號結束

一、信號誕生

信號誕生指的是觸發信號的事件發生,比如檢測到硬體異常、計時器超時、呼叫信號發送函數 kill 等。

二、信號在目標程序中註冊

in kernel/include/linux/sched.h struct task_struct { ... sigset_t blocked; struct sigpending pending; ... }; in kernel/include/linux/signal.h struct sigqueue { struct sigqueue *next; siginfo_t info; }; struct sigpending { struct sigqueue *head, **tail; sigset_t signal; };

在每一個程序中的 task_struct 結構裏,存在一個關於本程序中未處理信號的資料成員 struct sigpending pending。struct sigpending 中的 sigset_t signal 代表程序中所有未處理的信號集合,*head, **tail 分別指向一個 struct sigqueue 的結構鏈首尾,struct sigqueue 稱之為未處理信號資訊鏈。

信號在程序中註冊指的就是將信號值加入到程序的未處理信號集合中,也就是 sigpending 中的 sigset_t signal,並且信號所攜帶的資訊也被新增到未處理信號資訊鏈。只要信號在程序的未處理信號集合中,表明程序已經知道這些信號的存在,但還沒來得及處理,或者該信號被程序阻塞 (block)。

信號註冊與否,與發送信號的函數 kill/sigqueue 以及信號安裝函數 signal/sigaction() 無關,只與信號數值有關。信號值小於 SIGRTMIN 的信號最多只註冊一次,稱為非實時信號;信號值在 SIGRTMIN 及 SIGRTMAX 之間的信號,只要被進程接收到就被註冊,稱為實時信號。

三、信號在目標程序中註銷

在目標程序執行過程中,會檢測是否有信號等待處理,每次從系統空間返回到用戶空間時都做這樣的檢查。如果存在未處理信號且該信號沒有被程序阻塞 (sigset_t blocked 沒有被設置),則在運行相應的信號處理函數前,程序會把信號在未處理信號鏈中佔有的結構移除。

是否將信號從未處理信號集中刪除對於實時與非實時信號是不同的。對於非實時信號來說,由於在未處理信號資訊鏈中最多只佔用一個 sigqueue 結構,因此該結構被釋放後,應該把信號在未處理信號集中刪除;而對於實時信號來說,可能在未處理信號資訊鏈中佔用多個 sigqueue 結構,因此應該針對佔用 sigqueue 結構的數目區別對待:如果只佔用一個 sigqueue 結構(程序只收到該信號一次),則應該把信號在程序的未處理信號集中刪除。否則,不應該在程序的未處理信號集中刪除該信號。

四、信號結束

程序註銷信號後,立即執行相應的信號處理函數,執行完畢後,信號的本次發送對程序的影響徹底結束。

台南小新 發表在 痞客邦 PIXNET 留言(0) 人氣()