Linux程序訊號

2021-10-05 06:37:09 字數 2752 閱讀 3964

訊號是乙個軟體中斷。作業系統通過訊號告訴程序發生了某個事件,打斷程序當前的操作,去處理這個事件。

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.被阻塞的訊號產生時將保持在未決狀態,知道程序解除對此訊號 的阻塞,才會執行遞...