我們需要有一個能表示多個信號——信號集(signal set)的數據類型。POSIX.1定義了數據類型sigset_t以包含一個信號集,并且定義了下列五個處理信號集的函數。
#include <signal.h>int sigemptyset(sigset_t *set);int sigfillset(sigset_t *set);int sigaddset(sigset_t *set, int signo);int sigdelset(sigset_t *set, int signo);四個函數的返回值:若成功則返回0,若出錯則返回-1int sigismember(const sigset_t *set, int signo);返回值:若真則返回1,若假則返回0,若出錯則返回-1
函數sigemptyset初始化由set指向的信號集,清除其中所有信號。
函數sigfillset初始化由set指向的信號集,使其包括所有信號。
所有應用程序在使用信號集前,要對該信號集調用sigemptyset或sigfillset一次。這是因為C編譯器將把未賦初值的外部和靜態變量都初始化為0,而這是否與給定系統上信號集的實現相對應卻并不清楚。
一旦初始化了一個信號集,以后就可以在該信號集中增、刪特定的信號。
函數sigaddset將一個信號添加到現有集中,sigdelset則從信號集中刪除一個信號。
對所有以信號集作為參數的函數,我們總是以信號集地址作為向其傳送的參數。
實例
如果實現的信號數目少于一個整型量所包含的位數,則可用一位代表一個信號的方法實現信號集。我們假定一種實現有31種信號和32位整型值。
sigemptyset函數將整型量設置為0,sigfillset函數則將整型量中的各個位都設置為1。
這兩個函數可以在<signal.h>頭文件中實現為宏:
#define sigempty(ptr) (*(ptr) = 0)#define sigfillset(ptr) (*(ptr) = ~(sigset_t)0, 0)
注意,除了設置信號集各位為1外,sigfillset必須返回0,所以使用C語言的逗號運算符(逗號運算符是所有運算符中級別最低的),它將逗號運算符后的值作為表達式的返回值。
使用這種實現,sigaddset打開一位(將該位設置為1),sigdelset則關閉一位(將該位設置為0),sigismember測試一指定位。
因為沒有編號為0的信號,所以從信號編碼中減去1以得到要處理位的位編碼數。
程序清單10-9 sigaddset、sigdelset和sigismember的實現
#include <signal.h>#include <errno.h>/* <signal.h> usually defines NSIG to include signal number 0 */#define SIGBAD(signo) ((signo) <= 0 || (signo) >= NSIG)intsigaddset(sigset_t *set, int signo){ if (SIGBAD(signo)) { errno = EINVAL; return(-1); } *set |= 1 << (signo - 1); /* turn bit on */ return(0);}int sigdelset(sigset_t *set, int signo){ if (SIGBAD(signo)) { errno = EINVAL; return(-1); } *set &= ~(1 << (signo -1)); /* turn bit off */ return(0);}int sigismember(const sigset_t *set, int signo){ if (SIGBAD(signo)) { errno = EINVAL; return(-1); } return(*set & (1 << (signo - 1)) != 0);}
本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/。
新聞熱點
疑難解答