信號集操作函數
內核通過讀取未決信號集來判斷信號是否應被處理。信號屏蔽字mask可以影響未決信號集。而我們可以在應用程序中自定義set來改變mask。已達到屏蔽指定信號的目的。
信號集設定
?????? sigset_t? set;??????? // typedef unsigned long sigset_t;
int sigemptyset(sigset_t *set);?????????????????? 將某個信號集清0?????? ???? ???? 成功:0;失敗:-1
??? int sigfillset(sigset_t *set);?????????????????? ?????? 將某個信號集置1?????? ? ?? ???? 成功:0;失敗:-1
??? int sigaddset(sigset_t *set, int signum);???? ?????? 將某個信號加入信號集? ?? ?????? 成功:0;失敗:-1
??? int sigdelset(sigset_t *set, int signum);?????? ?????? 將某個信號清出信號集?? ? ?????? 成功:0;失敗:-1
??? int sigismember(const sigset_t *set, int signum);判斷某個信號是否在信號集中? 返回值:在集合:1;不在:0;出錯:-1?
??? sigset_t類型的本質是位圖。但不應該直接使用位操作,而應該使用上述函數,保證跨系統操作有效。
??? 對比認知select 函數。
sigprocmask函數
用來屏蔽信號、解除屏蔽也使用該函數。其本質,讀取或修改進程的信號屏蔽字(PCB中)
??? 嚴格注意,屏蔽信號:只是將信號處理延后執行(延至解除屏蔽);而忽略表示將信號丟處理。
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); 成功:0;失敗:-1,設置errno
參數:
?????? ?????? set:傳入參數,是一個位圖,set中哪位置1,就表示當前進程屏蔽哪個信號。
?????? ?????? oldset:傳出參數,保存舊的信號屏蔽集。
?????? ?????? how參數取值:?? 假設當前的信號屏蔽字為mask
- SIG_BLOCK: 當how設置為此值,set表示需要屏蔽的信號。相當于 mask = mask|set
- SIG_UNBLOCK: 當how設置為此,set表示需要解除屏蔽的信號。相當于 mask = mask & ~set
- SIG_SETMASK: 當how設置為此,set表示用于替代原始屏蔽及的新屏蔽集。相當于 mask = set若,調用sigprocmask解除了對當前若干個信號的阻塞,則在sigprocmask返回前,至少將其中一個信號遞達。
sigpending函數
讀取當前進程的未決信號集
int sigpending(sigset_t *set);?????? set傳出參數。?? 返回值:成功:0;失敗:-1,設置errno
練習:編寫程序。把所有常規信號的未決狀態打印至屏幕。????? ????????????? ?????? 【sigpending.c】
/*** printped.c ***/ #include<stdio.h> #include<unistd.h> #include<signal.h>void printped(sigset_t *ped) {int i;for(i = 1; i < 32; i++){if(sigismember(ped,i)){putchar('1');}else {putchar('0');}}printf("\n"); }int main() {sigset_t myset,oldset,ped;sigemptyset(&myset);sigaddset(&myset,SIGQUIT);sigprocmask(SIG_BLOCK,&myset,&oldset);while(1){sigpending(&ped);printped(&ped);sleep(1);}return 0; }
?