訊號是乙個軟體中斷。作業系統通過訊號告訴程序發生了某個事件,打斷程序當前的操作,去處理這個事件。
1.訊號的檢視
kill -l //檢視系統中的訊號種類
在linux作業系統中,一共有62中訊號。
34~64號訊號:後期擴充的,因為沒有具體對應事件,因此命名比較草率------可靠訊號。
訊號的生命週期:產生->在程序中註冊->在程序中登出->處理
2.訊號的產生
硬體條件產生訊號:
ctrl+c / ctrl+z / ctrl+|
軟體條件產生訊號:
kill -signum pid//命令
kill殺死乙個程序的原理就是向程序傳送乙個訊號,訊號有對應的事件,程序放下手頭工作去處理這個事件,然而事件的處理結果就是讓程序退出。kill預設傳送15號訊號。
訊號產生函式
int
main()
return0;
}
3.訊號在程序中的註冊
怎麼讓程序知道自己收到了某個訊號。pcb->struct sigpending->struct sigset_t。
sigset_t這個結構體中有乙個陣列成員,這個陣列用於實現乙個位圖。給程序傳送乙個訊號,就會將這個點陣圖中對應位置1,表示當前程序收到了這個訊號。位圖只能表示是否接收到了這個訊號,不能表示收到了多少個這樣的訊號。
新號的註冊不僅會修改位圖,還會為訊號組織乙個sigqueue節點新增到pcb的sigqueue鍊錶中。
1~31號非可靠訊號的註冊:若訊號註冊的時候點陣圖為0,則會建立乙個sigqueue節點並修改點陣圖為1,但若是點陣圖為1,則什麼都不做。
34~64號可靠訊號的註冊:不管位圖當前是多少,都會建立乙個節點,新增到鍊錶中,並修改點陣圖為1。
4.訊號在程序中的登出
為了保證乙個訊號不會被多次處理,因此訊號是先登出再處理,在pcb中刪除當前訊號資訊。
非可靠訊號的登出:因為非可靠訊號只會有乙個節點,因此刪除節點後,位圖直接置0。
可靠訊號的登出:因為可靠訊號有可能多次註冊,有多個節點,因此刪除節點後,需要判斷是否還有相同節點,若沒有才會將位圖置0。
5.訊號的處理
訊號表示乙個事件的到來,處理事件就是完成功能,在c語言中完成乙個功能的最小模組–函式。
其實每乙個訊號都對應有自己的事件處理函式,訊號到來去處理這個事件就是去執行這個處理函式。
訊號的處理方式
1.預設處理方式:作業系統中原定義好的每個訊號的處理方式。
2.忽略處理方式:處理方式就是忽略,什麼都不做。
3.自定義處理方式:自己定義乙個事件函式,使用這個函式替換核心中預設的處理函式,訊號到來就會呼叫我們所定義的函式了。
訊號處理函式
void
sigcb
(int signo)
intmain()
return0;
}
6.訊號的阻塞
並不是不接收訊號,訊號依然可以註冊,只是標識哪些訊號暫時不處理。
在pcb中有乙個位圖,點陣圖叫block點陣圖—阻塞訊號集合,這個集合中的訊號如果來了則暫時不處理。
void
sigcb
(int signo)
intmain()
return0;
}
在所有的訊號中,有兩個訊號比較特殊:sigkill-9/sigstop-19,這兩個訊號不可被阻塞,不可被忽略,不可被自定義。
7.sigchld和sigpipe訊號
子程序退出後會向父程序傳送sigchld訊號通知父程序。
但是因為sigchld訊號預設的處理方式是忽略,因此之前的程式中若不進行程序等待則不知道子程序的退出。
學了訊號之後,如果進行程序等待,而且還不想讓父程序阻塞,就可以自定義sigchld訊號的處理方式。
void
sigcb
(int signo)
}int
main()
pid =
fork()
;if(pid ==0)
while(1
)return0;
}
在程序間通訊中,我們使用管道時,所有讀端被關閉,則繼續寫入和套接字tcp斷開連線會觸發異常—sigpipe訊號。也可以通過自定義sigpipe訊號的處理方式來解決。
8.volatile關鍵字
用於修飾乙個變數,保持變數的記憶體可見性,(cup在處理的時候每次都重新從記憶體中獲取資料),防止編譯器過度優化。
在編譯程式的時候,如果使用了**優化,發現使用某個變數的頻率特別高,為了提高效率會將變數的值設定為某個暫存器的值,以後訪問資料的時候直接從暫存器訪問,減少了記憶體訪問的過程,提高效率。
但是這會造成**的邏輯混亂,因為讀取變數的值時是從記憶體中讀取,但是變數的值設定為暫存器的值,改變這個變數的值,只會讓暫存器中的值改變,記憶體中的值並沒有改變。
9.函式的重入
在多個執行流程中,同時進入乙個函式執行。
函式可重入:指的是函式重入之後,不會造成資料二義或者邏輯混亂。
函式不可重入:指的是函式重入之後,有可能造成資料二義或邏輯混亂。
函式是否可重入的判斷基準:這個函式是否對全域性變數進行了非原子的操作,若有則不可重入。
操作的原子性:操作一次性完成,中間不會被打斷。
原子操作:操作要麼一次完成,要麼就不做。
乙個函式若根本沒有操作全域性資料,或者操作全域性資料但是操作是原子性的,則是可以重入的。
Linux 程序訊號
概念 訊號是程序之間事件非同步通知的一種方式,屬於軟中斷。訊號處理常見方式 忽略此訊號。執行該訊號的預設處理動作。提供乙個訊號處理函式,要求核心在處理該訊號時切換到使用者態執行這個處理函式,這種方式稱為捕捉 catch 乙個訊號。產生訊號 捕捉訊號 核心如何實現訊號的捕捉 如果訊號的處理動作是使用者...
linux 程序訊號
signal 函式的使用方法簡單,但並不屬於 posix 標準,在各類 unix 平台上的實現不盡相同,因此其用途受 到了一定的限制。而 posix 標準定義的訊號處理介面是 sigaction 函式,其介面標頭檔案及原型如下 include int sigaction int signum,con...
Linux程序訊號 訊號處理
一 訊號相關概念 1.實際執行訊號的處理動作稱為訊號遞達 delivery 2.訊號從產生到遞達之間的狀態稱為訊號未決 pending 不一定會立即delivery 3.程序可以選擇阻塞 block 某個訊號。不會遞達 4.被阻塞的訊號產生時將保持在未決狀態,知道程序解除對此訊號 的阻塞,才會執行遞...