歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> Linux進程間通信(五) 信號通信之signal()、信號集函數組及其基礎實驗

Linux進程間通信(五) 信號通信之signal()、信號集函數組及其基礎實驗

日期:2017/3/3 16:21:15   编辑:關於Linux

上一節介紹進程間通信方式之一信號通信中的信號產生和捕捉函數,這一節介紹信號處理函數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已經按照咱們自定 義的函數運行。

Copyright © Linux教程網 All Rights Reserved