為了理解訊號,先從最熟悉的場景說起:
(1): 使用者輸入命令,在shell中啟動乙個前台程序。
(2): 使用者按下ctrl-c,這個鍵盤輸入產生乙個硬體中斷
(3): 如果cpu當前正在執行這個程序的**,則該程序的使用者空間**暫時停止執行,cpu從使用者態切換到核心態處理硬體中斷
(4):終端驅動程式將ctrl-c解釋為乙個sigint訊號,記在該程序的pcb中
(5):當某個時刻要從核心返回到該程序的使用者空間**繼續執行之前,首先處理pcb中記錄的訊號,當發現有乙個sigint訊號時,而這個訊號的預設處理動作是終止程序,
所以直接終止程序而不是返回到它的使用者空間**執行(提供訊號處理函式另論)
注意的是:shell中可以由乙個前台程序組和多個後台程序組,像sigint這樣的控制鍵產生的訊號,終端驅動程式只會傳送至前台程序,前台程序在執行到**段的任意地方時,都可以接受到這樣的訊號,從而訊號相對於程序來說是非同步的。
訊號產生的幾種方式:
(1):使用者按下終端鍵時候,例如ctrl-c產生sigint訊號
(2):硬體異常產生的訊號:除數為0,,無效的記憶體引用
(3):程序呼叫kill函式可將訊號傳送給另乙個程序或者是程序組。但是接受者和傳送訊號的所有者必須相同.或者是傳送訊號的程序的所有者為root
(4);當檢查到某種軟體條件已經產生,並將其通知有關程序時也產生訊號。
訊號是非同步事件的例子,我們不能通過檢查某個特定的變數來檢查乙個訊號是否發生,原因很簡單,訊號在任何時候都有可能發生,我們總不能寫一行使用者**,檢測一下特定的變數吧,這樣程式很是混亂,所以這個時候必須在訊號產生的時候告訴核心應該怎樣做。這樣的話,訊號處理函式signal(),感覺可以寫在**段的任何地方,這個函式的第乙個引數是訊號常量,第二個引數是訊號的處理函式,這個函式的作用只是告訴核心當產生某個特定的訊號時你應該怎麼做,也就是說當**段執行到這裡的時候,會在pcb中進行訊號處理函式指標的記錄,而非真正的取處理這個訊號,因為訊號可能尚未產生,這樣的話這個signal函式最好是寫在main函式的開頭,因為**段的執行是在不同的程序的上下文之間不停的切換,如果系統很是繁忙的話,可能已經產生了某種訊號,但是signal函式可能由於位置太靠後,而未做相應的記錄,導致訊號的處理不是我們自己定義的處理函式的結果。
訊號處理的三種方式:
(1):忽略該訊號,(2);捕捉訊號,執行使用者的訊號處理函式 (3):執行系統預設動作。
注意:有兩種訊號不能忽略,sigkill與sigstop,原因是向超級使用者提供了程序終止或者是停止的可靠方法。這樣的話,這兩個訊號也就不能**捉.
可以通過kill -l 檢視系統的訊號.
unix環境高階程式設計之訊號篇(一)
一 引言 訊號是軟體中斷,很比較重要的應用程式都需要處理訊號。訊號提供了一種處理非同步事件的方法,例如,中斷使用者鍵入中斷鍵,則會通過訊號機制停止乙個程式,或及早終止管道中的下乙個程式。二 概念 每乙個訊號都有乙個名字。這些名字都是以sig開頭,如sigabrt是夭折訊號,當程序呼叫abort函式時...
UNIX環境高階程式設計之第10章 訊號
訊號是軟體中斷.很多比較重要的應用程式都需要處理訊號.訊號提供一種處理非同步時間的方法,例如,終端使用者鍵入中斷鍵,會通過訊號機制停止乙個程式,或及早終止管道中的下乙個程式.首先每個訊號都有乙個名字.這些名字都是以sig開頭.例如,sigabrt是夭折訊號,當程序呼叫abort函式是產生這種訊號.u...
unix環境高階程式設計之環境搭建
首先,apue.h不是系統自有的,而是做著自己的寫的,因此,本書程式設計的第一步就是將該檔案包含下來 2.執行一下 ls,發現多了乙個apue.3e,cd 命令進入該目錄 3.執行 make 第三步一般都會出錯,提示是需要 bsd,執行 apt yum install y libbsd dev,重新...