您好,登錄后才能下訂單哦!
今天在閱讀《linux內核完全剖析-基于0.12內核》一書中信號(sigal.c)處理這一小節時發現自己原來對信號機制的理解并不是很到位,通過查閱資料整理記錄下來。
幾個概念:
1)信號是什么:
一個信號就是一個消息,它通知進程一個某種類型的事件已經在系統中發生了;
用戶在終端按下某些鍵,終端驅動程序會發送信號給前臺進程;例如ctrl-c產生SIGINT信號;ctrl-\產生SIGQUIT信號;ctrl-z產生SIGSTP信號;
硬件異常產生信號;這些信號由硬件檢測到并通知內核,由內核通知當前進程,例如當前進程出現除0錯誤;
kill系統調用,一個進程可以調用kill發送信號給另一個進程;
內核檢測到某種軟件設置的條件發生時也可能發信號給一個進程,例如alarm系統調用就會導致出現這樣的場景;
2)阻塞信號、待處理信號:
阻塞信號指的是某個進程阻塞了某個或某些信號集;阻塞并不是說進程不接收指定的信號集;而是指信號仍可以被進程接收(放入待處理信號集),但是不處理。從內核具體的實現可以很好的理解;
內核在task_struct中維護進程信號阻塞向量(block)和pending向量(待處理信號集);block與pending一一對應,對于某一個信號:若pending對應bit置位而block復位,標識信號已發生并接收且當前未被進程阻塞,可以立刻處理(默認或用戶自定義信號處理函數);若pending對應bit復位而block置位,標識信號還未被接收到,即使接收到了,那么也被當前進程阻塞(即不被立刻處理,需要接觸阻塞后才可處理)。。。
3)信號處理細微問題:
待處理信號可能被阻塞:若當前進程捕捉一個SIGINT信號,并且當前正在運行該信號的處理程序,那么如果另一個SIGINT信號傳遞到這個進程,那么個這個SIGINT將變成待處理的,直到處理程序返回。
待處理信號不會排隊等待:這個我的理解是與內核實現有關(內核一般使用位向量標識信號集),好像現在linux中有實時信號集是可以排隊的(以后看到了再學習吧。。。)
系統調用可以被中斷:一般是對慢速系統調用來說的,被中斷的慢速系統調用在信號處理程序返回時不再繼續,而是立即返回用戶一個錯誤條件,并將errno置為EINTR;
4)可移植到信號處理程序
可移植信號語義為如下:
只有這個處理程序當前正在處理的那種類型的信號被阻塞;
和所有信號是實現一樣,信號不會排隊等待;
只要可能,被中斷的系統調用會重啟;(用戶實現:顯式循環調用系統調用;內核實現:恢復系統調用參數,讓用戶棧中的eip重新指向系統調用中斷指令;)
一旦設置了信號處理程序,它就一直保持,直到重新設置。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。