通过编程实现信号的捕获和屏蔽,例如:捕获“Ctrl-C”信号时,打印I have get SIGINT,捕获“Ctrl-\”信号时,打印I have get SIGQUIT;设置进程屏蔽字,.取消对SIGINT的屏蔽,再次按下“Ctrl-C”,查看结果。
设置信号屏蔽用的是sigprocmask(SIG_SETMASK,&sigset,NULL),但是这种状态下当输入已经屏蔽的信号时并没有真正的忽略,而是进入待处理状态,当这种屏蔽被去掉之后,该函数会处理待处理的信号,并把多个相同的待处理信号当做一个信号处理,所以系统输出了一个I have get SIGINT。取消屏蔽用的函数是sigprocmask(SIG_UNBLOCK,&sigset,NULL)。
sigaction.c
#include<unistd.h> #include<stdio.h> #include<signal.h> #include<stdlib.h> void handler(int sig) { if (sig == SIGINT) { printf("I have get SIGINT\n"); } else if (sig == SIGQUIT) { printf("I have get SIGQUIT\n"); } } int main() { sigset_t sigset,ign; struct sigaction act; sigemptyset(&sigset); sigemptyset(&ign); //向信号中添加信号SIGINT sigaddset(&sigset,SIGINT); //设置处理函数和信号集 act.sa_handler=handler; sigemptyset(&act.sa_mask); act.sa_flags=0; sigaction(SIGINT,&act,0); sigaction(SIGQUIT,&act,0); printf("Wait the signal...\n"); pause();//挂起进程 等待信号 pause(); printf("Ctrl+C屏蔽中\n"); sigprocmask(SIG_SETMASK,&sigset,NULL);//暂时进入待处理状态 pause();//挂起进程 等待信号 sigprocmask(SIG_UNBLOCK,&sigset,NULL);//在信号屏蔽字中删除sigset中的信号 printf("屏蔽结束\n"); printf("Wait the signal SIGINT..\n"); pause();//挂起进程 等待信号 }
截图如下:
运行sigaction.c并输入Ctrl+C 输入Ctrl+\
此时进程运行到SIGINT被屏蔽,输入Ctrl+C测试
但此时Ctrl+\没有被屏蔽,输入Ctrl+\
此时屏蔽已经删除,Ctrl+C测试有效