要明白訊號處理函式的使用,就要先知道訊號的捕捉設定,什麼時候會呼叫訊號處理函式和其執行的流程是什麼,下圖完整的展示了訊號捕捉的設定,以及訊號處理函式的觸發機制:
所以,從上圖可以知道,只有當程式中斷,異常或系統呼叫,才會進入核心態,也只有進入了核心態才能處理訊號,在這裡初學者常常有乙個誤區,他們會覺得如果我在程式中沒有設定中斷、不出現異常、不使用系統呼叫,那就就不會進入核心態,也就不會處理訊號了!這是對作業系統錯誤的理解,由於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/*在開發過程中,我們往往不希望破壞linux原有的訊號處理函式,所以核心也給我們提供了兩個專門用於使用者自定義的訊號(10號訊號siguse1和12號訊號siguse2。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+\退出程式)
1 #include 2 #include 34void 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 23 typedef void (*sighandler_t)(int
)4 sighandler_t signal(int signum, sighandler_t handler)
#include #includevoid 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...