Linux系统编程----7(信号集,信号屏蔽,信号捕捉)
信號集操作函數
內核通過讀取未決信號集來判斷信號是否應被處理。信號屏蔽字 mask 可以影響未決信號集。而我們可以在應 用程序中自定義 set 來改變 mask。已達到屏蔽指定信號的目的。
信號集設定
sigset_t 類型的本質是位圖。但不應該直接使用位操作,而應該使用上述函數,保證跨系統操作有效。
sigprocmask 函數
用來屏蔽信號、解除屏蔽也使用該函數。其本質,讀取或修改進程的信號屏蔽字(PCB 中)
嚴格注意
屏蔽信號:只是將信號處理延后執行(延至解除屏蔽);而忽略表示將信號丟處理。
函數格式
int sigprocmask(int how,const sigset_t* set,sigset_t* oldset); 成功:0;失敗:-1,設置 errno
參數
set:傳入參數,是一個位圖,set 中哪位置 1,就表示當前進程屏蔽哪個信號。
oldset:傳出參數,保存舊的信號屏蔽集。
how 參數取值: 假設當前的信號屏蔽字為 mask
sigpending 函數
讀取當前進程的未決信號集
int sigpending(sigset_t* set); set 傳出參數。 返回值:成功:0;失敗:-1,設置 errno
編寫程序。把所有常規信號的未決狀態打印至屏幕。
/** 打印未決信號集*/#include<stdio.h> #include<signal.h> #include<unistd.h>void printped(sigset_t * ped) {int i;//常用的是前32個信號for(i = 1; i < 32; i++ ){if(sigismember(ped,i) == 1){ //在集合中putchar('1');}else{putchar('0');} } printf("\n"); }int main(void ){sigset_t myset, oldset ,ped;sigemptyset(&myset);sigaddset(&myset,SIGQUIT);//屏蔽系統本身3號信號sigaddset(&myset,SIGINT);//屏蔽系統本身的2號信號sigaddset(&myset,SIGTSTP);sigaddset(&myset,SIGSEGV);sigaddset(&myset,SIGKILL); sigprocmask(SIG_BLOCK,&myset,&oldset);while(1){sigpending(&ped);//判斷集合中每個信號的對應位是0還是1printped(&ped);sleep(1);}return 0; }9號信號和19號信號不允許設置屏蔽
信號捕捉
signal 函數
注冊一個信號捕捉函數:
typedef void(*sighandler_t)(int); sighandler_t signal(int signum,sighandler_t handler);該函數由 ANSI 定義,由于歷史原因在不同版本的 Unix 和不同版本的 Linux 中可能有不同的行為。因此應該盡 量避免使用它,取而代之使用 sigaction 函數。
void (*signal (int signum,void ( *sighandler_t)(int)))(int); #include<stdio.h> #include<sys/time.h> #include<signal.h>void myfunc(int signo) {printf("hello world\n"); }int main(void) {struct itimerval it,oldit;signal(SIGALRM,myfunc); //注冊SIGALRM信號的捕捉處理函數//sighandler_t tml=signal(SIGALRM,myfunc);it.it_value.tv_sec=5;//定時5秒中it.it_value.tv_usec=0;//0微秒it.it_interval.tv_sec=3;//第一個和第二個之間間隔時間3秒it.it_interval.tv_usec=0;if(setitimer(ITIMER_REAL,&it,&oldit) == -1){perror("setitimer error");return -1; } while(1);return 0; }
第一個出來是5秒,隨后都是3秒出來一個
sigaction 函數
修改信號處理動作(通常在 Linux 用其來注冊一個信號的捕捉函數)
int sigaction (int signum,const struct sigaction*act,struct sigaction*oldact) 成功:0;失敗:-1,設置 errno參數:
struct sigaction 結構體
};
sa_restorer:該元素是過時的,不應該使用,POSIX.1 標準將不指定該元素。(棄用) sa_sigaction:當 sa_flags 被指定為 SA_SIGINFO 標志時,使用該信號處理程序。(很少使用)
重點掌握:
sa_handler:指定信號捕捉后的處理函數名(即注冊函數)。也可賦值為 SIG_IGN 表忽略 或 SIG_DFL 表執行默 認動作
sa_mask: 調用信號處理函數時,所要屏蔽的信號集合(信號屏蔽字)。注意:僅在處理函數被調用期間屏蔽 生效,是臨時性設置。
sa_flags:通常設置為 0,表使用默認屬性。
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<signal.h>void docatch(int signo) {printf("%d signal is catched\n",signo); }int main(void) {int ret;struct sigaction act;act.sa_handler = docatch;sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask,SIGQUIT);act.sa_flags = 0; //默認屬性 信號捕捉函數執行期間自動屏蔽本信號 ret = sigaction(SIGINT,&act,NULL);if(ret < 0){ perror("sigaction error");exit(1);} while(1);return 0; }信號捕捉特性
總結
以上是生活随笔為你收集整理的Linux系统编程----7(信号集,信号屏蔽,信号捕捉)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 江南百景图结实的拐杖怎么获得
- 下一篇: Linux系统编程----8(竞态条件,