訊號 訊號處理函式(捕捉)

2022-01-31 08:53:26 字數 3153 閱讀 8942

要明白訊號處理函式的使用,就要先知道訊號的捕捉設定,什麼時候會呼叫訊號處理函式和其執行的流程是什麼,下圖完整的展示了訊號捕捉的設定,以及訊號處理函式的觸發機制: 

所以,從上圖可以知道,只有當程式中斷,異常或系統呼叫,才會進入核心態,也只有進入了核心態才能處理訊號,在這裡初學者常常有乙個誤區,他們會覺得如果我在程式中沒有設定中斷、不出現異常、不使用系統呼叫,那就就不會進入核心態,也就不會處理訊號了!這是對作業系統錯誤的理解,由於linux是分時作業系統(但可以改成實時的如:ucos就是linux修改而來的實時系統,很多人在此有誤區),所以當時間片用完時,就會進入核心態,進行程序排程,在此就會處理訊號了!

核心給我們提供了乙個用於註冊使用者自定義訊號處理函式 的函式sigaction:

1 #include 2

3int sigaction(int signum, const

struct sigaction *act, struct sigaction *oldact);45

struct

sigaction 定義:

6struct

sigaction ;

1314

sa_handler : 早期的捕捉函式

15sa_sigaction : 新新增的捕捉函式,可以傳參 , 和sa_handler互斥,兩者通過sa_flags選擇採用哪種捕捉函式

16 sa_mask : 在執行捕捉函式時,設定阻塞其它訊號,sa_mask |程序阻塞訊號集,退出捕捉函式後,還原回原有的阻塞訊號集

17(即用於訊號處理函式中是否還處理訊號的到達)

18 sa_flags : sa_siginfo 或者 0

,上面兩個函式呼叫哪乙個,0呼叫sa_handler所指向的函式,1代表sa_sigaction所指向的函式

19 sa_restorer : 保留,已過時

所以我們要做的步驟是: 

1)宣告sigaction 結構體 

2)構造sigaction 結構體 

3)用sigaction 函式註冊sigaction 結構體

1 #include 2 #include 34/*

5* #include

6* int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);7*

8* struct sigaction 定義:

9* struct sigaction ;

17*/

1819

void do_sig(int

num)

2028 printf("

num = %d\n

",num);29}

3031

int main(void)32

62return0;

63}6465

6667

測試方法:

68 執行該程式,按下ctrl+c傳送sigint訊號,此時會進入使用者定義的訊號處理函式

69輸出如下:

70 ************************

71 ************************

72 ************************(按下ctrl+c)

73i am do_sig

74 n = 2n = 1n = 0num = 2

75 ************************

76 ************************

77 ************************

78 ************************(按下ctrl+c)

79i am do_sig

80 n = 2n = 1n = 0num = 2

81 ************************

82 ************************(按下ctrl+\退出程式)

在開發過程中,我們往往不希望破壞linux原有的訊號處理函式,所以核心也給我們提供了兩個專門用於使用者自定義的訊號(10號訊號siguse1和12號訊號siguse2。 

1 #include 2 #include 3

4void do_sig(int

num)59

10int main(void)11

26return0;

27}2829

30測試方法:

31 在乙個終端中執行該程式(此時在該終端中會一直輸出:********************)

32 在另一終端中輸入ps -aux命令查詢執行該程式的程序id號

33 並輸入kill -10

程序id號 向該程式傳送10號訊息sigusr1

34此時執行該程式的終端中會輸出:i am do_sig

另一方面,c庫函式也為我們提供了乙個封裝更高層,介面更簡單的函式signal

1 include 2

3 typedef void (*sighandler_t)(int

)4 sighandler_t signal(int signum, sighandler_t handler)

#include #include 

void do_sig(int

n)int main(void

)

return0;

}執行後按ctrl+c即可檢視效果,若要關閉程式則按ctrl+\

Linux 訊號的捕捉過程以及訊號捕捉函式

我們都說訊號的產生之後不是被立即處理的,而是在合適的時候,那麼合適的時候是什麼時候呢?訊號又是怎麼 捉的呢?合適的時候是指 從核心態切換為使用者態時進行訊號的捕捉 在linux下,我們會發現我們有時候會有一些檔案不能進入,有一些檔案不能建立,其實這就是一種許可權。核心態和使用者態都是一種狀態,這兩種...

golang 訊號捕捉和處理

捕捉和處理訊號可以實現優雅start和restart等。golang的signal提供了相關的方法。這裡是乙個模板,目錄結構 sig sig.go test.go 先看如何呼叫 1.new出乙個物件 2.register訊號與對應的處理函式 3.定義os.signal型別的channel,呼叫sig...

Linux訊號捕捉及其處理

一 signal訊號處理機制 可以用函式signal註冊乙個訊號捕捉函式,其函式原型為 include typedef void sighandler t int sighandler t signal int signum,sighandler t handler 下面用乙個例子來介紹signal...