歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux管理 >> Linux問題解決

linux知識大講堂:Linux的信號和阻塞


1. 信號掩碼——被阻塞的信號集


每個進程都有一個用來描述哪些信號傳送來將被阻塞的信號集,如果某種信號在某個進程的阻塞信號集中,則傳送到該進程的此種信號將會被阻塞。當前被進程阻塞的信號集也叫信號掩碼,類型為sigset_t。每個進程都有自己的信號掩碼,且創建子進程時,子進程會繼承父進程的信號掩碼。


2. 信號阻塞和忽略的區別


阻塞的概念與忽略信號是不同的:操作系統在信號被進程解除阻塞之前不會將信號傳遞出去,被阻塞的信號也不會影響進程的行為,信號只是暫時被阻止傳遞;當進程忽略一個信號時,信號會被傳遞出去,但進程將信號丟棄。


3. 信號集的操作


信號集可以由以下幾個函數操作:


int sigemptyset(sigset_t *set); //清空信號集


int sigfillset(sigset_t *set); //將所有信號填充進set中


int sigaddset(sigset_t *set, int signum); //往set中添加信號signum


int sigdelset(sigset_t *set, int signum); //從set中移除信號signum


int sigismember(const sigset_t *set, int signum); //判斷signnum是不是包含在set中,在返回1,不在返回0


初始化往往可以用sigemptyset()將信號集清空,再用sigaddset()向信號集中添加信號;或者可以使用sigfillset()將所有信號添加到信號集,再用sigdelset()將某信號從中刪除掉。


4. sigprocmask()介紹


可以使用函數sigprocmask()來檢查或者修改進程的信號掩碼。函數信息如下:


#include


int sigprocmask ( int how, const sigset_t *restrict set,


sigset_t *restrict old );


參數how 是一個整數,說明信號掩碼的修改方式:


SIG_BLOCK --- 將set指向的信號集中的信號添加到當前阻塞信號集中;


SIG_UNBLOCK --- 從當前阻塞信號集中移除set指向的信號集中的信號;


SIG_SETMASK --- 指定set所指向的信號集為當前阻塞信號集。


此外,如果參數set 為NULL, 說明不需要修改,如果old 為NULL,sigprocmask會將修改之前的信號集放在*old 之中返回。//本文轉自www.45it.com電腦軟硬件應用網


5.sigaction()回顧


在前面有用過sigaction()函數:


include


int sigaction(int signum,const struct sigaction *act,


const struct sigaction *oldact);


該函數是用於注冊一個信號處理函數。參數結構體sigaction與函數同名,具體信息如下:


struct sigaction {


void (*sa_handler)(int); //老類型的信號處理函數指針


void (*sa_sigaction)(int, siginfo_t *, void *);//新類型的信號處理函數指針


sigset_t sa_mask; //將要被阻塞的信號集合


int sa_flags; //信號處理方式掩碼


void (*sa_restorer)(void); //保留

}

 


5.1 sa_handler:一個函數指針,用於指向原型為void handler(int)的信號處理函數地址(老類型的信號處理函數);


5.2 sa_sigaction:也是一個函數指針,用於指向原型為:


void handler(int (新類型的信號處理函數);


三個參數的含義為:


iSignNum:傳入的信號


pSignInfo:與該信號相關的一些信息,它是個結構體


pReserved:保留,現沒用


5.3 sa_handler和sa_sigaction只應該有一個生效,如果想采用老的信號處理機制,就應該讓sa_handler指向正確的信號處理函數;否則應該讓sa_sigaction指向正確的信號處理函數,並且讓字段sa_flags包含SA_SIGINFO選項。


5.4 sa_mask是一個包含信號集合的結構體,該結構體內的信號表示在進行信號處理時,將要被阻塞的信號。該信號集可以用前面標題3提到的5個函數來進行操作。


5.5 字段sa_flags是一組掩碼的合成值,指示信號處理時所應該采取的一些行為,各掩碼的含義為:


(1)SA_RESETHAND ---處理完畢要捕捉的信號後,將自動撤消信號處理函數的注冊,即必須再重新注冊信號處理函數,才能繼續處理接下來產生的信號。


(2)SA_NODEFER ---在處理信號時,如果又發生了其它的信號,則立即進入其它信號的處理,等其它信號處理完畢後,再繼續處理當前的信號,即遞規地處理。如果sa_flags包含了該掩碼,則結構體sigaction的sa_mask將無效;


(3)SA_RESTART--- 如果在發生信號時,程序正阻塞在某個系統調用,例如調用read()函數,則在處理完畢信號後,接著從阻塞的系統返回。該掩碼符合普通的程序處理流程,所以一般來說,應該設置該掩碼,否則信號處理完後,阻塞的系統調用將會返回失敗;


(4)SA_SIGINFO ---指示結構體的信號處理函數指針是哪個有效,如果sa_flags包含該掩碼,則sa_sigactiion指針有效,否則是sa_handler指針有效。


需要注意的是:


函數sigprocmask是全程阻塞,在sigprocmask中設置了阻塞集合後,被阻塞的信號將不能再被信號處理函數捕捉,直到重新設置阻塞信號集合。而在sigaction()注冊信號處理函數時,選擇阻塞的信號集只是在處理捕捉的信號時,才對指定的其他信號進行阻塞。

Copyright © Linux教程網 All Rights Reserved