我們需要有一個(gè)能表示多個(gè)信號(hào)——信號(hào)集(signal set)的數(shù)據(jù)類型。POSIX.1定義了數(shù)據(jù)類型sigset_t以包含一個(gè)信號(hào)集,并且定義了下列五個(gè)處理信號(hào)集的函數(shù)。
#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);四個(gè)函數(shù)的返回值:若成功則返回0,若出錯(cuò)則返回-1int sigismember(const sigset_t *set, int signo);返回值:若真則返回1,若假則返回0,若出錯(cuò)則返回-1
函數(shù)sigemptyset初始化由set指向的信號(hào)集,清除其中所有信號(hào)。
函數(shù)sigfillset初始化由set指向的信號(hào)集,使其包括所有信號(hào)。
所有應(yīng)用程序在使用信號(hào)集前,要對(duì)該信號(hào)集調(diào)用sigemptyset或sigfillset一次。這是因?yàn)镃編譯器將把未賦初值的外部和靜態(tài)變量都初始化為0,而這是否與給定系統(tǒng)上信號(hào)集的實(shí)現(xiàn)相對(duì)應(yīng)卻并不清楚。
一旦初始化了一個(gè)信號(hào)集,以后就可以在該信號(hào)集中增、刪特定的信號(hào)。
函數(shù)sigaddset將一個(gè)信號(hào)添加到現(xiàn)有集中,sigdelset則從信號(hào)集中刪除一個(gè)信號(hào)。
對(duì)所有以信號(hào)集作為參數(shù)的函數(shù),我們總是以信號(hào)集地址作為向其傳送的參數(shù)。
實(shí)例
如果實(shí)現(xiàn)的信號(hào)數(shù)目少于一個(gè)整型量所包含的位數(shù),則可用一位代表一個(gè)信號(hào)的方法實(shí)現(xiàn)信號(hào)集。我們假定一種實(shí)現(xiàn)有31種信號(hào)和32位整型值。
sigemptyset函數(shù)將整型量設(shè)置為0,sigfillset函數(shù)則將整型量中的各個(gè)位都設(shè)置為1。
這兩個(gè)函數(shù)可以在<signal.h>頭文件中實(shí)現(xiàn)為宏:
#define sigempty(ptr) (*(ptr) = 0)#define sigfillset(ptr) (*(ptr) = ~(sigset_t)0, 0)
注意,除了設(shè)置信號(hào)集各位為1外,sigfillset必須返回0,所以使用C語言的逗號(hào)運(yùn)算符(逗號(hào)運(yùn)算符是所有運(yùn)算符中級(jí)別最低的),它將逗號(hào)運(yùn)算符后的值作為表達(dá)式的返回值。
使用這種實(shí)現(xiàn),sigaddset打開一位(將該位設(shè)置為1),sigdelset則關(guān)閉一位(將該位設(shè)置為0),sigismember測(cè)試一指定位。
因?yàn)闆]有編號(hào)為0的信號(hào),所以從信號(hào)編碼中減去1以得到要處理位的位編碼數(shù)。
程序清單10-9 sigaddset、sigdelset和sigismember的實(shí)現(xiàn)
#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);}
本篇博文內(nèi)容摘自《UNIX環(huán)境高級(jí)編程》(第二版),僅作個(gè)人學(xué)習(xí)記錄所用。關(guān)于本書可參考:http://www.apuebook.com/。
|
新聞熱點(diǎn)
疑難解答
圖片精選