上一節介紹進程間通信方式之一信號通信中的信號產生和捕捉函數,這一節介紹信號處理函數signal()函 數和信號集函數組,接上一節http://blog.csdn.net/mybelief321/article/details/9078193
強烈建 議做最後一個實驗!
信號處理方法
信號處理的方法主要有以下兩種:
① 使用 signal() 函數;
② 使用信號集函數組。
使用signal()函數
函數說明
使 用signal()函數處理時,只需指出要處理的信號和處理函數即可。它主要用於前32種非實時信號的處理,不支 持信號傳遞信息。Linux還支持一個更健壯更新的信號處理函數呢,它就是 sigaction(),推薦使用這個函數 。
函數格式
這裡 signal() 這個函數的原型我當時看了頭有點大,還是先說明一下:首先該函數原型整體指向一個無 返回值並且帶一個整形參數的函數指針,也就是信號的原始配置函數;接著該原型又帶有兩個參數,其中第2 個參數可以是用戶自定義的信號處理函數的函數指針。不明白也沒事,後邊做實驗就明白了,會用就行了。
這裡要說明的是 sigaction()函數中第2個和第3個參數用到的 sigaction 結構,下表為 siaction的定義 :
sa_handler 是一個函數指針,指定信號處理函數,這裡除可以是咱們自定義的處理函數外,還可以為 SIG_DFL(采用默認的處理方式)或SIG_IGN(忽略信號)。它的處理函數只有一個參數,即信號值。
sa_mask 是一個信號集,它可以指定在信號處理程序執行過程中哪些信號應當被屏蔽,在調用信號捕 獲函數前,該信號集要加入到信號的信號屏蔽字中。
sa_flags 中包含了很多標志位,是對信號進行處 理的各個選擇項。它的常見可選值如下表所示:
基礎實驗1
本實驗是表明如何使用 signal()函數捕捉相應信號,並做出給定的處理。這 裡,my_func就是信號處理的函數指針,咱們也可以將其改為SIG_IGN或SIG_DFL查看運行結果。實驗代碼如下 :
signal.c文件下載:http://download.csdn.net/detail/mybelief321/5568687
編譯運行後出現如下的結果:
此時程序被掛起,一直等待信 號。
如果在鍵盤上按下 Ctrl+c 組合鍵,結果如下
如果在鍵盤上按下 Ctrl+ \ 組合鍵,結果如下
可見進程收到相應的信號後,轉去執行咱們自定義函數了。你可以將my_func換為SIG_IGN或者 SIG_DFL,看看有什麼不同。
基礎實驗2
本實驗實現的功能同實驗1一樣,只不過是換成了 sigaction()函數,程序如下
sigaction.c文件點此下載
編譯運行後結果如下
第一次按組合鍵“Ctrl+c”, 結果如下
第二次按組合鍵“Ctrl+c”,結 果如下
我建議你把25行的換成 SA_RESTARTHAND等試一試,會加深理解的
信號集函數組
函數說明
使用信號集函數組處 理信號時設計一系列的函數,這些函數按照先後的調用次序可分為以下幾大模塊:創建信號集、注冊信號處理 函數及檢測信號。
其中,創建信號集主要用於處理用戶感興趣的一些信號,其函數包括以下幾個:
sigemptyset(): 將信號集初始化為空
sigfillset(): 將信號集初始化為包含所有已定義的信 號集
sigaddset(): 將指定信號加入到信號集中
sigdelset(): 將指定信號從信號集中刪除
sigismember(): 查詢指定信號是否在信號集中
注冊信號處理函數主要用於決定進程如何處理 信號。這裡要注意的是,信號集裡的信號並不是真正可以處理的信號,只有當信號的狀態處於非阻塞狀態時才 會真正起作用。因此,首先使用 sigprocmask() 函數檢測並更改信號屏蔽字(信號屏蔽字是用來指定當前被 阻塞的一組信號,它們不會被進程接收),然後使用 sigaction()函數來定義進程接收到特定信號後的行為。
檢測信號是信號處理的後續步驟,因為被阻塞的信號不會傳遞給進程,所以這些信號就處於“未處理 ”狀態(也就是進程不清除它的存在)。sigaction()函數允許進程檢測“未處理”信號,並進一步決定對它 們做何處理。
函數格式
在sigprocmask()中,若set 是一個非空指針,則參數 how 表示函數的操作方式;若how為空,則表示忽略 此操作。
總之,在處理信號時,一般遵循下圖所示的操作流程
基礎實驗3(強烈建議做這個實驗啊)
該實驗首先把 SIGQUIT、SIGINT兩個信號加入信號集,然後 將該信號集設為阻塞狀態,並進入用戶輸入狀態。咱們只需要按任意鍵,就可以將信號集設置為非阻塞狀態, 再對這兩個信號分別操作,其中SIGQUIT執行默認操作,而SIGINT執行用戶自定義函數的操作。
sigset.c文件:http://download.csdn.net/detail/mybelief321/5570687
編譯運行結果如下
按任意鍵
接 著按組合鍵:Ctrl+c
接著按組合鍵:Ctrl+\
如果在運行時,先直接按組合鍵:Ctrl+\,結果如下
對比結果可以看到,在新號處於阻塞狀態時,所發出的信號對進程不起作用,並且該信號進入待處 理狀態。按下任意鍵,信號脫離了阻塞狀態時,咱們發出的信號才能正常運行。這裡SIGINT已經按照咱們自定 義的函數運行。