linux下的信號屏蔽字
阿新 • • 發佈:2017-06-28
end 沒有 開發環境 include 打印 put red mem 自定義
信號的表示
我們知道linux下,可以通過kill命令向進程發送信號.
當進程收到信號,執行處理動作被稱為遞達;
當進程接收到信號,還未來得及處理被稱之為未決(pending);
進程可以選擇阻塞某個信號,當某個信號被阻塞(block)時,永遠不會遞達!
因此,與這三種處理相對應,在進程的pcb中,存在三張位圖來描述信號相關信息!
block、pending與handler
block是一個位圖,如果某個信號block為1,則表示其永遠也不會遞達,也就是說永遠都不會執行handler表中的函數.
pending也是一個位圖,如果某個信號pending為1,表示其已經產生,如果為0,表示沒有產生.
handler指針數組,表示某個信號處理時的默認動作,SIG_DFL表示默認處理,SIG_IGN表示忽略該信號,其它表示自定義處理.
信號的屏蔽與恢復
知道了這些,我編寫了一個程序,來驗證一下屏蔽、恢復屏蔽一個信號.
//////////////////////////////////// //文件說明:pending.c //作者:高小調 //創建時間:2017年06月28日 星期三 15時15分45秒 //開發環境:Kali Linux/g++ v6.3.0 //////////////////////////////////// #include<stdio.h> #include<signal.h> #include<unistd.h> #include<stdlib.h> //屏蔽SIGINT void blockSIGINT(){ sigset_t set; sigemptyset(&set); sigaddset(&set,SIGINT); sigprocmask(SIG_BLOCK,&set,NULL); } //恢復SIGINT void recoverSIGINT(){ sigset_t set; sigemptyset(&set); sigprocmask(SIG_SETMASK,&set,NULL); } //打印未決表 void printPending(sigset_t *set){ for(int i=1; i<=31; ++i){ if(sigismember(set,i)){ putchar(‘1‘); }else{ putchar(‘0‘); } } putchar(‘\n‘); } void handler(int sig){ printf("the No.%d signal is deliver!\n",sig); } int main(){ signal(SIGINT,handler); int count = 5; printf("block the SIGINT %ds later!\n",count); sigset_t set; sigemptyset(&set); //先將SIGINT屏蔽掉 while(1){ if(count==0){ blockSIGINT(); printf("SIGINT has benn blocked!\n"); break; } sigpending(&set); printPending(&set); sleep(1); --count; } //再把它恢復過來 printf("recover the SIGINT %ds later!\n",10-count); while(1){ if(count==10){ recoverSIGINT(); printf("SIGINT has been recovered!\n"); break; } //恢復之前,信號被阻塞,因此如果產生SIGINT信號,將會處於未決狀態 sigpending(&set); printPending(&set); count++; sleep(1); } while(1); return 0; }
linux下的信號屏蔽字