linux/unix信號機制學習

今天在閱讀《linux內核徹底剖析-基於0.12內核》一書中信號(sigal.c)處理這一小節時發現本身原來對信號機制的理解並非很到位,經過查閱資料整理記錄下來。 linux

幾個概念:
1)信號是什麼:

    一個信號就是一個消息,它通知進程一個某種類型的事件已經在系統中發生了; 函數

  • 用戶在終端按下某些鍵,終端驅動程序會發送信號給前臺進程;例如ctrl-c產生SIGINT信號;ctrl-\產生SIGQUIT信號;ctrl-z產生SIGSTP信號; 學習

  • 硬件異常產生信號;這些信號由硬件檢測到並通知內核,由內核通知當前進程,例如當前進程出現除0錯誤; 進程

  • kill系統調用,一個進程能夠調用kill發送信號給另外一個進程; 事件

  • 內核檢測到某種軟件設置的條件發生時也可能發信號給一個進程,例如alarm系統調用就會致使出現這樣的場景; ip

2)阻塞信號、待處理信號:
    阻塞信號指的是某個進程阻塞了某個或某些信號集;阻塞並非說進程不接收指定的信號集;而是指信號仍能夠被進程接收(放入待處理信號集),可是不處理。從內核具體的實現能夠很好的理解;
    內核在task_struct中維護進程信號阻塞向量(block)和pending向量(待處理信號集);block與pending一一對應,對於某一個信號:若pending對應bit置位而block復位,標識信號已發生並接收且當前未被進程阻塞,能夠馬上處理(默認或用戶自定義信號處理函數);若pending對應bit復位而block置位,標識信號還未被接收到,即便接收到了,那麼也被當前進程阻塞(即不被馬上處理,須要接觸阻塞後纔可處理)。。。 it

3)信號處理細微問題: 軟件

  1. 待處理信號可能被阻塞:若當前進程捕捉一個SIGINT信號,而且當前正在運行該信號的處理程序,那麼若是另外一個SIGINT信號傳遞到這個進程,那麼個這個SIGINT將變成待處理的,直處處理程序返回。
  2. 待處理信號不會排隊等待:這個個人理解是與內核實現有關(內核通常使用位向量標識信號集),好像如今linux中有實時信號集是能夠排隊的(之後看到了再學習吧。。。)
  3. 系統調用能夠被中斷:通常是對慢速系統調用來講的,被中斷的慢速系統調用在信號處理程序返回時再也不繼續,而是當即返回用戶一個錯誤條件,並將errno置爲EINTR;

4)可移植到信號處理程序
可移植信號語義爲以下: 循環

  1. 只有這個處理程序當前正在處理的那種類型的信號被阻塞;
  2. 和全部信號是實現同樣,信號不會排隊等待;
  3. 只要可能,被中斷的系統調用會重啓;(用戶實現:顯式循環調用系統調用;內核實現:恢復系統調用參數,讓用戶棧中的eip從新指向系統調用中斷指令;)
  4. 一旦設置了信號處理程序,它就一直保持,直到從新設置。
相關文章
相關標籤/搜索