一、內核通過讀取未決信號集來判斷信號是否應該被處理。信號屏蔽字mask可以影響未決信號集。爲我們可以在應用程序中自定義set來改變mask,來達到屏蔽指定信號的目的。
二、信號集設定:
sigset_t set;//typedef unsigned long sigset_t;
int sigemptyset(sigset_t *set); //將某個信號集清零
int sigfillset(sigset_t *set); //將某個信號集置1
int sigaddset(sigset_t *set, int signum); //將某個信號加入信號集
int sigdelset(sigset_t *set, int signum); //將某個信號集清出信號集
int sigismember(const sigset_t *set, int signum); //判斷某個信號是否在信號集中
以上前四個函數執行成功返回0,失敗返回-1。函數返回1時,表示在集合中;返回0時,表示不在集合中。
sigset_t類型其實本質上是位圖。但是在Linux中我們一般不用位操作去處理,而是使用上面的五個函數來處理。(這麼做是爲了保證代碼跨平臺也能有效,類型select函數)
三、sigprocmask函數
1、用來屏蔽信號、解除屏蔽。本質上是修改進程的信號屏蔽字(進程的信號屏蔽字在PCB中)。這裏要注意:屏蔽信號是將信號處理屏蔽掉,這樣做只會讓信號處理延後到屏蔽解除;而忽略信號(3種信號處理方式之一)則表示將信號丟棄掉。
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); //成功返回0,失敗返回-1
2、參數:
①set:傳入參數,是一個位圖,set中哪些位置爲1,就表示當前進程屏蔽哪些信號。
②oldset:If oldset is non-NULL, the previous value of the signal mask is stored
in oldset。
③how參數:(假設當前信號屏蔽字爲mask)
SIG_BLOCK:當how取此值時,set表示需要屏蔽的信號,相當於mask=mask|set
SIG_UNBLOCK:當how取此值時,set表示需要解除屏蔽的信號。相當於mask=mask&~set
SIG_SETMASK:當how設置爲此,set表示用於替代原來屏蔽集的新屏蔽集。相當於mask=set
3、如果調用sigprocmask解除了對當前若干個信號的阻塞,則在sigprocmask返回前,至少將其中一個信號遞達!
四、信號集設定、sigprocmask函數、未決信號集、阻塞信號集的關係圖
五、sigpending函數
讀取當前進程的未決信號集
int sigpending(sigset_t *set); //成功返回0.失敗返回-1
六、練習:編寫程序,把所有常規信號的未決狀態打印出來。