Linux學習之旅(19) 訊號(1)

2021-09-12 14:31:40 字數 3950 閱讀 6564

訊號:linux的訊號機制是從unix的基礎上發展來的,在linux中一共有64個訊號(實際只有62個,另外兩個被廢棄了),其中前32是從unix中繼承來的,用來控制程序。另外32個是liunx的訊號有被稱為實時訊號,用來操作硬體。

在linux系統中通過kill -l命令可以檢視這寫訊號:

作業系統對訊號的處理一般有3種方式:

一、預設 二、忽略   三、捕捉

預設方式:作業系統為每個程序都設定了預設的動作(5種),當程序接收到訊號後系統就會使用該訊號對應的動作。

這五種動作分別是:

(1)term:終止當前程序。

(2)core:終止當前程序並且生成core檔案(用於gdb除錯)

(3)ign:   忽略該訊號

(4)stop:暫停當前程序

(5)cont:繼續執行暫停的程式。

(*最後一行為該訊號在什麼情況下會產生)

通過man 7 signal 命令可以檢視signal的具體資訊。

忽略方式:當某個程序接收到訊號,會忽略它,即不去處理。一般的訊號都可以被設定忽略,但sigkill和sigstop是不能被忽略。(如果可以忽略就會產出核心無法殺死的程序,這會非常的危險)。

捕捉方式:即當程序接收到訊號後,不會去使用預設的方法,而是使用使用者自定義的方式去處理這個訊號。

那訊號是如何產生的那?

訊號編號

訊號名稱

產生原因

1sighup

當使用者退出shell時,由該shell啟動的所有程序將收到這個訊號,預設動作為終止程序

2sigint

當使用者按下ctrl+c組合鍵時,使用者終端向該終端啟動並正在執行的程序傳送此訊號,預設終止程序

3sigquit

當使用者按下ctrl+\組合鍵時,使用者終端向該終端啟動並正在執行的程序傳送此訊號,預設終止程序

4sigill

cpu檢測到某程序執行了非法指令。預設終止程序並產生core檔案

5sigtrap

由斷點或者其他trap指令產生

6sigabrt

呼叫abort函式時產生

7sigbus

非法訪問記憶體位址,包括記憶體對齊出錯

8sigfpe

在發生致命的運算錯誤時發出。包括浮點數運算錯誤,溢位及除數為0等所有演算法錯誤

9sigkill

無條件終止程序

10siguse1

使用者自定義訊號,可以在程式中使用

11sigse**

無效記憶體訪問

12sigusr2

使用者自定義訊號,可以在程式中使用

13sigpipe

向沒有讀端的管道寫資料

14sigalrm

定時器超時

15sigterm

程式結束訊號

16sigstkflt

linux專用,數學協處理器的棧異常

17sigchid

子程序結束時,父程序接收的訊號

18sigcont

繼續執行暫停程序執行

19sigstop

暫停乙個程序

20sigtstp

互動停止程序(ctrl+z)

21sigttin

當乙個後台程序試圖讀控制終端時,終端驅動程式產生

22sigttou

當乙個後台程序試圖寫控制終端時,終端驅動程式產生

23sigurg

通知程序已經發生了乙個緊急情況。在網路連線上接到非規定的波特率的資料時,此訊號可選擇的產生。

24sigxcpu

當cpu時間限制超時的時候

25sigxfsz

超過檔案的最大長度設定。

26si**talrm

虛擬時鐘超時時產生該訊號,只計算cpu使用時間

27sigprof

和si**talrm類似,計算cpu和執行系統呼叫的時間

28sigwinch

視窗大小發生變化時產生該訊號

29sigio

向程序發出乙個非同步的i/o事件

30siggpwr

關機31

sigsys

無效的系統呼叫

在程序的pcb中儲存兩個訊號集(未決訊號集和阻塞訊號集),當程序接收到乙個訊號時,作業系統核心會將該程序未決訊號集中的對應的訊號位置為1,表示這個訊號還沒有被真正的執行,然後去檢視對應的阻塞訊號集,如果阻塞訊號集中對應的狀態位為0,那麼該訊號執行,對應未決訊號集中的1重新置為0(遞達態)。如果為1,那麼這個訊號被阻塞。並且前32個訊號不支援排隊,即如果未決訊號集中的狀態一旦為1,那麼之後同樣的訊號不會被接收。後32為支援排隊。

這時我們知道如果需要忽略程序某個訊號,只需要將該程序對應的阻塞訊號集對應訊號位置上的狀態位置為1,就可以了,那具體如何操作那?實際上我們時無法直接去修改pcb中的阻塞訊號集的,不過linux系統為我們提供了訊號集處理的函式。

訊號集的處理函式:

sigset_t為訊號集(結構體,佔128個位元組,可以通過sizeof()檢視)

int sigemptyset(sigset_t *set); //將訊號集的狀態為全部置為0

int sigfillset(sigset_t *set); //將訊號集的狀態為全部置為1

int sigaddset(sigset_t *set); //將訊號集中指定的狀態置為1

int sigdelset(sigset_t *set); //將訊號集中指定的狀態置為0

int sigismember(const sigset_t *set,int signo);//檢視訊號集中對應訊號的狀態位

int sigprocmask(int how,const sigset_t *set,sigset_t *oset);

/*函式功能:讀取或更改程序的訊號阻塞訊號集

引數說明:

(1)how

sig_block :將set訊號集新增到當前訊號集,相當於 mask=mask|set

sig_unblock:使用set訊號集解除阻塞訊號集的訊號,相當於 mask=mask&(~set)

sig_setmask:將阻塞訊號集替換為set訊號集。相當於mask=set

(2)set

set訊號集,更改阻塞訊號集。

(3)oset

oset傳出引數,將阻塞訊號集通過oset傳出

返回值:

若成功返回0,出錯返回-1

*/

我們可以通過sigset_t定義乙個訊號集,然後通過相應的函式對訊號集進行設定,然後將它通過sigprocmask()函式註冊進系統中。

int sigpending(sigset_t *set);

/*函式功能:

讀取當前程序的未決訊號集,通過set引數傳出。

返回值:

成功返回0,失敗返回-1

*/

程式:設定阻塞sigint(ctrl+c)和sigquit (ctrl+\)10秒

linux學習之旅(1) Linux簡介

作業系統是什麼?作業系統 英語 operating system,縮寫作 os 是管理計算機硬體與軟體資源的電腦程式,同時也是計算機系統的核心與基石。作業系統需要處理如管理與配置記憶體 決定系統資源供需的優先次序 控制輸入與輸出裝置 操作網路與管理檔案系統等基本事務。作業系統也提供乙個讓使用者與系統...

萌新的linux之旅19

系統正常引導過程 如果引導程式boot損壞 446位元組是啟動引導 dd if dev zero of dev vda bs 446 count 1 注意一定是446 多了或少了都不能正常引導修復 保證selinux是disabled 然後重啟,發現一直在booting,即無法引導系統系統 關閉虛擬...

c primer plus 學習之旅 1

c語言的起源 1972年,貝爾實驗室的丹尼斯 里奇和肯 湯姆遜在開發unix作業系統時設計了c語言 可移植性及利害關係 由於c語言與unix關係密切,unix系統通常會將c編譯器作為軟體包的一部分。而windows系統底層是dos所以在一些大廠中要求linux 程式設計的7個步驟 編譯器和鏈結器 編...