Linux 訊號機制 (二)

2021-07-02 22:18:37 字數 2176 閱讀 4099

推薦一篇好文章

文章二:

程序即將從核心態返回使用者態的時候,才會處理訊號(執行訊號處理函式)

使用者程序什麼時候從核心態返回使用者態呢?

系統呼叫(使用者主動進入核心)

中斷 (使用者程序被動進入核心)

被排程執行 (使用者從等待執行,變為正在執行)

訊號處理函式時使用者態函式,但是需要在核心態的條件下執行。所以需要一定的trick.

核心處理乙個程序收的訊號的時機是在程序從核心態返回到使用者態時。 所以乙個程序在核心態執行的時候,軟終端訊號並不會立即起作用,需要等到使用者態的時候才處理。 程序只有處理完 訊號才會返回使用者態,程序在使用者態下不會有未處理的訊號。

核心處理乙個程序收到的軟中斷訊號是在該程序的上下文中,因此,程序必須處於執行狀態。如果程序收到乙個要捕捉的訊號,那麼程序從核心態返回使用者態時執行 使用者定義的函式。而且執行使用者定義的函式的方法很巧妙,核心是在使用者棧上建立乙個新的層,該層中將返回位址的值設定成使用者定義的處理函式的位址,這樣程序 從核心返回彈出棧頂時就返回到使用者定義的函式處,從函式返回再彈出棧頂時,才返回原先進入核心的地方,接著原來的地方繼續執行。這樣做的原因是使用者定義的 處理函式不能且不允許在核心態下執行(如果使用者定義的函式在核心態下執行的話,使用者就可以獲得任何許可權)。

第一,在一些系統中,當乙個程序處理完中斷訊號返回使用者態之前,核心清除使用者區中設定的對該訊號的處理例程的地

址,即下一次程序對該訊號的處理方法又改為預設值,除非在下一次訊號到來之前再次使用signal系統呼叫。這可能會使得程序在呼叫signal之前又得

到該訊號而導致退出。在bsd中,核心不再清除該位址。但不清除該位址可能使得程序因為過多過快的得到某個訊號而導致堆疊溢位。為了避免出現上述情況。在

bsd系統中,核心模擬了對硬體中斷的處理方法,即在處理某個中斷時,阻止接收新的該類中斷

linux下應該不會清除註冊的函式位址,另外linux下是允許 訊號處理函式重入的。

第二個要引起注意的是,如果要捕捉的訊號發生於程序正在乙個系統呼叫中時,並且該程序睡眠在可中斷的優先順序上(若系統呼叫未睡眠而是在執行,根據上面的分

析,等該系統呼叫執行完畢後再處理訊號),這時該訊號引起程序作一次longjmp,跳出睡眠狀態,返回使用者態並執行訊號處理例程。當從訊號處理例程返回

時,程序就象從系統呼叫返回一樣,但返回了乙個錯誤如-1,並將errno設定為eintr,指出該次系統呼叫曾經被中斷。這要注意的是,bsd系統中內

核可以自動地重新開始系統呼叫,或者如上面所述手動設定重啟。

這裡的意思是: 程序因為系統呼叫處於可中斷的睡眠狀態下, 接受到了乙個訊號跳出了睡眠狀態。 這本身是不合理的,因為在等待系統呼叫的完成。 所以需要自動重新開始系統呼叫。

第三個要注意的地方:若程序睡眠在可中斷的優先順序上,則當它收到乙個要忽略的訊號時,該程序被喚醒,但不做longjmp,一般是繼續睡眠。但使用者感覺不

到程序曾經被喚醒,而是象沒有發生過該訊號一樣。所以能夠使pause、sleep等函式從掛起態返回的訊號必須要有訊號處理函式,如果沒有什麼動作,可

以將處理函式設為空。

這裡的意思是: 若程序睡眠在可中斷的優先順序上,但是收到的訊號預設狀態是忽略。該程序被喚醒,但是會繼續睡眠,使用者感覺不到程序曾經被喚醒。 (這裡的意思是,會將該程序加入到可執行佇列,但是訊號的預設動作是忽略,程序還是會繼續睡眠(如何繼續睡眠呢? 重新呼叫系統呼叫嗎?還是怎麼樣)。)

第四個要注意的地方:核心對子程序終止(sigcld)訊號的處理方法與其他訊號有所區別。當程序正常或異常終止時,核心都向其父程序發乙個sigcld

訊號,預設情況下,父程序忽略該訊號,就象沒有收到該訊號似的,如果父程序希望獲得子程序終止的狀態,則應該事先用signal函式為sigcld訊號設

置訊號處理程式,在訊號處理程式中呼叫wait

sigcld訊號的作用是喚醒乙個睡眠在可被中斷優先順序上的程序。如果該程序捕捉了這個訊號,就象普通訊號處理一樣轉到處理例程。如果程序忽略該訊號,則

什麼也不做。其實wait不一定放在訊號處理函式中,但這樣的話因為不知道子程序何時終止,在子程序終止前,wait將使父程序掛起休眠。

wait系統呼叫可以放在 中斷處理函式中嗎, 其原理是怎麼樣的呢?

Linux 信 號 機 制

前面介紹了訊號的基本概念,在這一節中,我們將介紹核心如何實現訊號機制。即核心如何向乙個程序傳送訊號 程序如何接收乙個訊號 程序怎樣控制自己對訊號的反應 核心在什麼時機處理和怎樣處理程序收到的訊號。還要介紹一下setjmp和longjmp在訊號中起到的作用。1 核心對訊號的基本處理方法 核心給乙個程序...

linux 訊號機制

本文旨在弄懂linux中的訊號工作原理 kill l 命令可以檢視linux下所有訊號 2.1 使用者在終端按下某些鍵時,終端驅動程式會傳送訊號給前台程序 例如ctrl c產生sigint訊號,ctrl 產生sigquit訊號,ctrl z產生sigtstp訊號 2.2 硬體異常產生訊號,這些條件由...

LINUX訊號機制

在電腦科學中,訊號是unix 類unix以及其他posix相容的作業系統中程序間通訊的一種有限制的方式。它是一種非同步的通知機制,用來提醒程序乙個事件已經發生。當乙個訊號傳送給乙個程序,作業系統中斷了程序正常的控制流程,此時,任何非原子操作都將被中斷。如果程序定義了訊號的處理函式,那麼它將被執行,否...