1、信号集
有一种数据结构能把60多种信号全部装进去
信号集结构
typedef struct {
unsigned long sig[2];
//两个无符号long,64位,表示64个信号
//为0代表信号没来,当有一个为1时,之后来的信号就不能立即处理
//要排队等待
}sigset_t;
2、信号处理相关函数
- 2.1、sigemptyset();全部设为0
- 2.2、sigfillset();全部设为1
- 2.3、sigaddset(),sigdelset()添加删除某个信号
- 2.4、sigprocmask,sigmember,一个进程对应一个信号集
用来记录当前屏蔽,阻塞了那些信号,如果我们把某个位置设为1.就表示屏蔽了某个信号
如果这个信号集中有很多个信号为都设为了1,那么都会被阻塞而不会被改进程接收到
sigprocmask就能设置该进程对应的信号集中的内容
3、sigprocmask信号函数范例演式
void sig_quit()
{
printf("收到信号\n");
}
int main()
{
//声明两个信号集
sigset_t newmask, oldmask;
//将现在进程的信号集的SIGQUIT的处理函数设置为sig_quit
if (signal(SIGQUIT, sig_quit) == SIG_ERR)
{
printf("无法捕捉SIGQUIT信号\n");
exit(1);
}
//将newmask信号集全部设为0
sigemptyset(&newmask);
//给newmask信号集添加上拒绝SIGQUIT信号
sigaddset(&newmask, SIGQUIT);
//SIG_BLOCK的参数,意思是将第二个参数设为本进程的信号集,而现在本进程的
//信号集赋给oldmask
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
{
printf("sigprocmask(SIG_BLOCK)失败\n");
exit(1);
}
printf("休息10秒,此时无法接受sigquit信号\n");
sleep(10);
printf("休息结束\n");
//判断newmask信号集中有没有屏蔽SIGQUOIT
if (sigismember(&newmask, SIGQUIT))
{
printf("sigquit信号被屏蔽\n");
}
else
{
printf("sigquit信号没有被屏蔽\n");
}
if (sigismember(&newmask, SIGHUP))
{
printf("SIGHUP信号被屏蔽\n");
}
else
{
printf("SIGHUP信号没有被屏蔽\n");
}
//SIG_SETMASK的参数意思是,将第二个参数设为本进程的信号级,老的为null
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
{
printf("sigprocmask(SIG_SETMASK, &oldmask, NULL)失败\n");
exit(1);
}
printf("sigprocmask(SIG_SETMASK, &oldmask, NULL)0成功\n");
if (sigismember(&oldmask, SIGQUIT))
{
printf("SIGqUIT信号被屏蔽\n");
}
else
{
printf("SIGQUIT信号没有别屏蔽,可以发送sigquit信号了,休眠10秒\n");
int mysle = sleep(10);
if (mysle > 0)
{
printf("sleep没有睡够,剩余%d秒\n", mysle);
}
}
printf("再见");
return 0;
}
运行结果:
这里面有一个比较有意思的地方,那就是覆盖之前的函数,非常像js
例如:
void sig_quit()
{
printf("收到信号\n");
//这样进入这个函数一次之后
//SIGQUIT的处理函数就会被设置为SIG_DFL
if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)
{
printf("无法捕捉SIGQUIT信号\n");
exit(1);
}
}
int main()
{
if (signal(SIGQUIT, sig_quit) == SIG_ERR)
{
printf("无法捕捉SIGQUIT信号\n");
exit(1);
}
}