訊號處理機制的原理:
核心給乙個程序傳送軟中斷訊號的方法,是在程序所在的程序表項的訊號域設定對應於該訊號的位。這裡要補充的是,如果訊號傳送給乙個正在睡眠的程序,那麼要 看該程序進入睡眠的優先順序,如果程序睡眠在可被中斷的優先順序上,則喚醒程序;否則僅設定程序表中訊號域相應的位,而不喚醒程序。這一點比較重要,因為程序 檢查是否收到訊號的時機是:乙個程序在即將從核心態返回到使用者態時;或者,在乙個程序要進入或離開乙個適當的低排程優先順序睡眠狀態時。
核心處理乙個程序收到的訊號的時機是在乙個程序從核心態返回使用者態時。所以,當乙個程序在核心態下執行時,軟中斷訊號並不立即起作用,要等到將返回使用者態 時才處理。程序只有處理完訊號才會返回使用者態(上面的例子程式中,在步驟5中,解除阻塞後,先列印caught sigquit,再列印sigquit unblocked,即在sigprocmask返回前,訊號處理程式先執行),程序在使用者態下不會有未處理完的訊號。
核心處理乙個程序收到的軟中斷訊號是在該程序的上下文中,因此,程序必須處於執行狀態。如果程序收到乙個要捕捉的訊號,那麼程序從核心態返回使用者態時執行 使用者定義的函式。而且執行使用者定義的函式的方法很巧妙,核心是在使用者棧上建立乙個新的層,該層中將返回位址的值設定成使用者定義的處理函式的位址,這樣程序 從核心返回彈出棧頂時就返回到使用者定義的函式處,從函式返回再彈出棧頂時,才返回原先進入核心的地方,接著原來的地方繼續執行。這樣做的原因是使用者定義的 處理函式不能且不允許在核心態下執行(如果使用者定義的函式在核心態下執行的話,使用者就可以獲得任何許可權)。
在訊號的處理方法中有幾點特別要引起注意。第一,在一些系統中,當乙個程序處理完中斷訊號返回使用者態之前,核心清除使用者區中設定的對該訊號的處理例程的地 址,即下一次程序對該訊號的處理方法又改為預設值,除非在下一次訊號到來之前再次使用signal系統呼叫。這可能會使得程序在呼叫signal之前又得 到該訊號而導致退出。在bsd中,核心不再清除該位址。但不清除該位址可能使得程序因為過多過快的得到某個訊號而導致堆疊溢位。為了避免出現上述情況。在 bsd系統中,核心模擬了對硬體中斷的處理方法,即在處理某個中斷時,阻止接收新的該類中斷。
第二個要引起注意的是,如果要捕捉的訊號發生於程序正在乙個系統呼叫中時,並且該程序睡眠在可中斷的優先順序上(若系統呼叫未睡眠而是在執行,根據上面的分 析,等該系統呼叫執行完畢後再處理訊號),這時該訊號引起程序作一次longjmp,跳出睡眠狀態,返回使用者態並執行訊號處理例程。當從訊號處理例程返回 時,程序就象從系統呼叫返回一樣,但返回了乙個錯誤如-1,並將errno設定為eintr,指出該次系統呼叫曾經被中斷。這要注意的是,bsd系統中內 核可以自動地重新開始系統呼叫,或者手如上面所述手動設定重啟。
第三個要注意的地方:若程序睡眠在可中斷的優先順序上,則當它收到乙個要忽略的訊號時,該程序被喚醒,但不做longjmp,一般是繼續睡眠。但使用者感覺不 到程序曾經被喚醒,而是象沒有發生過該訊號一樣。所以能夠使pause、sleep等函式從掛起態返回的訊號必須要有訊號處理函式,如果沒有什麼動作,可 以將處理函式設為空。
第四個要注意的地方:核心對子程序終止(sigcld)訊號的處理方法與其他訊號有所區別。當程序正常或異常終止時,核心都向其父程序發乙個sigcld 訊號,預設情況下,父程序忽略該訊號,就象沒有收到該訊號似的,如果父程序希望獲得子程序終止的狀態,則應該事先用signal函式為sigcld訊號設 置訊號處理程式,在訊號處理程式中呼叫wait。
sigcld訊號的作用是喚醒乙個睡眠在可被中斷優先順序上的程序。如果該程序捕捉了這個訊號,就象普通訊號處理一樣轉到處理例程。如果程序忽略該訊號,則 什麼也不做。其實wait不一定放在訊號處理函式中,但這樣的話因為不知道子程序何時終止,在子程序終止前,wait將使父程序掛起休眠。
當應用程式向特定程序傳送訊號時,呼叫kill或raise函式。
Linux訊號處理機制
程式錯誤 除零,非法記憶體訪問 外部訊號 終端ctrl c產生sgint訊號,定時器到期產生sigalrm 顯式請求 kill函式允許程序傳送任何訊號給其他程序或程序組。目前linux支援64種訊號。訊號分為非實時訊號 不可靠訊號 和實時訊號 可靠訊號 兩種型別,對應於 linux 的訊號值為 1 ...
Linux訊號處理機制(二) 阻塞訊號
訊號在核心中一般有三種狀態 1 訊號遞達 delivery 實際執行訊號的處理動作稱為訊號遞達 2 訊號未決 pending 訊號從產生到遞達之間的狀態 3 訊號阻塞 block 被阻塞的訊號產生時將保持在未決狀態,直到程序解除對此訊號的阻塞,才執行遞達的動作 注意 阻塞與忽略是不同的,只要訊號被阻...
Linux核心訊號處理機制介紹
本文簡單介紹下linux訊號處理機制,為介紹二進位制翻譯下訊號處理機制做乙個鋪墊。本文主要參考書目 linux核心源 情景分析 程式錯誤 除零,非法記憶體訪問 外部訊號 終端ctrl c產生sgint訊號,定時器到期產生sigalrm 顯式請求 kill函式允許程序傳送任何訊號給其他程序或程序組。在...