Linux系統(tǒng)編程—信號集操作函數(shù)
先來回顧一下未決信號集是怎么回事。
信號從產(chǎn)生到抵達目的地,叫作信號遞達。而信號從產(chǎn)生到遞達的中間狀態(tài),叫作信號的未決狀態(tài)。產(chǎn)生未決狀態(tài)的原因有可能是信號受到阻塞了,也就是信號屏蔽字(或稱阻塞信號集,mask)對應位被置1。阻塞信號集和未決信號集均是由內(nèi)核維護的,整個過程如下圖示:
我們有時需要屏蔽某個信號,就需要去修改阻塞信號集。那么,我們該如何修改阻塞信號集?系統(tǒng)提供的一個方法是,我們先創(chuàng)建一個跟阻塞信號集一樣的集合,再利用它去修改阻塞信號集。
系統(tǒng)提供了一系列的信號集設定函數(shù)。這些函數(shù)如下所示:
- sigset_t set;
 - 信號集數(shù)據(jù)類型,本質(zhì)是typedef unsigned long sigset_t;
 - int sigemptyset(sigset_t *set);
 - 將某個信號集清0
 - int sigfillset(sigset_t *set);
 - 將某個信號集置1
 - int sigaddset(sigset_t *set, int signum);
 - 將某個信號加入信號集int sigdelset(sigset_t *set, int signum);
 - 將某個信號清出信號集以上幾個函數(shù)返回值均是:成功:0;失敗:-1
 - int sigismember(const sigset_t *set, int signum);
 - 判斷某個信號是否在信號集中返回值:在集合:1;不在:0;出錯:-1
 
使用以上這些函數(shù)創(chuàng)建完信號集后,要如何去改變阻塞信號集呢?系統(tǒng)又提供了一個函數(shù):sigprocmask函數(shù)。
sigprocmask函數(shù)可以用來屏蔽信號,也可以用來解除屏蔽信號,其本質(zhì)就是利用我們創(chuàng)建的信號集去改變阻塞信號集。
函數(shù)原型:
- int sigprocmask(int how, const sigset_t set, sigset_t oldset);
 
返回值:
成功:0;失敗:-1,設置errno
參數(shù)解釋:
- set:傳入?yún)?shù),是一個位圖,set中哪位置1,就表示當前進程屏蔽哪個信號。
 - oldset:傳出參數(shù),保存舊的信號屏蔽集。這個與setitimer有點相似。
 
how參數(shù)取值:
假設當前的信號屏蔽字為mask
- SIG_BLOCK:當how設置為此值,set表示需要屏蔽的信號。相當于 mask = mask | set
 - SIG_UNBLOCK:當how設置為此,set表示需要解除屏蔽的信號。相當于 mask = mask & ~set
 - SIG_SETMASK:當how設置為此,set表示用于替代原始屏蔽及的新屏蔽集。相當于 mask = set若,調(diào)用sigprocmask解除了對當前若干個信號的阻塞,則在sigprocmask返回前,至少將其中一個信號遞達。
 
我們?nèi)绾巫x取未決信號集?系統(tǒng)提供了sigpending函數(shù)。
函數(shù)原型:
- int sigpending(sigset_t *set);
 
參數(shù)說明:set傳出參數(shù)。
返回值:
返回值:成功:0;失?。?1,設置errno
例:把所有常規(guī)信號的未決狀態(tài)打印至屏幕。
- #include
 - #include
 - #include
 - void printPending(sigset_t *set)
 - {
 - int i = 0;
 - for (i = 0; i < 32; i++) {
 - if (sigismember(set, i) == 1)
 - printf("1");
 - else
 - printf("0");
 - }
 - printf("\n");
 - }
 - int main()
 - {
 - sigset_t set, oldset, pendset;
 - sigemptyset(&set);
 - sigaddset(&set, SIGQUIT); // ctrl + \ 將產(chǎn)生SIGQUIT信號
 - sigprocmask(SIG_BLOCK, &set, &oldset);
 - while (1) {
 - sigpending(&pendset);
 - printPending(&pendset); // 寫一個函數(shù)打印未決信號集
 - sleep(1);
 - }
 - }
 
本文授權(quán)轉(zhuǎn)載自公眾號「良許Linux」。良許,世界500強外企Linux開發(fā)工程師,公眾號里分享大量Linux干貨,歡迎關注!

















 
 
 

 
 
 
 