通过编程实现信号的捕获和屏蔽,例如:捕获“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测试有效