第二十五篇:使用 sigaction 函式實現可靠訊號

穆晨發表於2017-01-28

前言

       在前文中,講述了一個可靠訊號的示例。它分成幾個步驟組成( 請參考前文 )。在 Linux 系統程式設計中,有個方法可以將這些步驟給整合起來,讓我們使用起來更加的方便。

       那就是呼叫 sigaction 函式。

sigaction() 函式

       原型:int sigaction (int signo, const struct sigaction * restrict act, struct sigaction *restrict oact)

       作用:將訊號及其處理函式關聯起來,但這個註冊函式中,訊號處理函式是放在一個結構體中的,這個結構體除了註冊函式,還可以存放一些其他資訊,以實現可靠訊號機制

       

       其中,第一個欄位是訊號處理函式的地址;第二個欄位是在接收到所等待的訊號前,需要遮蔽的訊號的訊號集( 從訊號處理函式返回之後就會恢復到原先的訊號遮蔽字 );

       另外兩個欄位一般設定為 0 和 NULL,用的比較少。

       最後一個引數如果非空責將返回這個訊號原本對應的的訊號處理結構體。

程式碼實現

       下面程式是一個使用 sigaction 函式實現可靠訊號的示例:

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <signal.h>
 4 
 5 static void sig_quit (int);
 6 
 7 int main (void) {
 8 
 9     // 初始化訊號處理結構體
10     struct sigaction act;
11     act.sa_handler = sig_quit;
12     // 這一步可以根據需要,遮蔽指定的訊號,其對應訊號處理函式執行完畢以後,訊號遮蔽字又會恢復到呼叫前的狀態。
13     sigemptyset (&act.sa_mask);
14     act.sa_flags = 0;
15     act.sa_sigaction = NULL;
16 
17     // 記得引數型別是引用型別!
18     if (sigaction (SIGQUIT, &act, NULL) < 0) {
19         printf ("註冊訊號處理函式失敗\n");
20         return 1;
21     }
22 
23     // 在此階段進入訊號處理函式並返回後,不會繼續掛起狀態,而是進入到下一條語句。
24     sleep (50);
25 
26     return 0;
27 }
28 
29 static void sig_quit (int signo)
30 {    
31     printf("捕捉到退出訊號\n");
32 
33     // 將對退出訊號的處理設定為關閉程式
34     if (signal (SIGQUIT, SIG_DFL) == SIG_ERR) {
35         printf("設定退出訊號處理函式失敗\n");
36     }
37 }

執行測試

       

       發現了一個問題:未列印” 捕捉到退出訊號\n " ( 31 行 ),這個問題只能留待日後解決。

小結

       sigaction 結構體的後兩個引數的具體功能,請參閱相關資料。

相關文章