信号集:
一个进程必须能够记住它当前阻塞了哪些信号
0000001000000000000000 标志位
我们需要被称为信号集的数据类型 能把60多个信号都表示下。
linux中用sigset_t结构类型来表示信号集;64位
typedef struct{
unsigned long sig[2];
}sigset_t;
信号集相关函数:
a) sigemptyset() 清空信号集
b) sigfillset() 把所有信号集都设置成1
c) 用sigaddset(), sigdelset() 增加信号 删除信号
d) sigprocmask() sigmember()
一个进程里对应一个信号集 用来记录屏蔽和阻塞了哪些信号 1 即为屏蔽 无法传递给该进程
如果有很多个信号位都被设置为1, 那么所有这些被设置为1的信号都属于当前被阻塞的而不能传递到该进程的信号。
sigprocmask()函数,就能够设置该进程所对应的信号的内容
范例:
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
void sig_quit(int signo)
{
printf("收到了SIGQUIT\n");
if(signal(SIGQUIT, SIG_DFL) == SIG_ERR)
{
printf("无法为sigquit信号设置缺省处理(终止进程)\n");
exit(1);
}
}
int main()
{
sigset_t newmask, oldmask;
if(signal(SIGQUIT, sig_quit) == SIG_ERR) // SIGQUIT为“ctrl + /”
{
printf("无法捕捉SIGQUIT信号\n");
exit(1);
}
sigemptyset(&newmask);
sigaddset(&newmask, SIGQUIT);
//sigprocmask第一个参数
if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
{
printf("sigprocmask(SIG_BLOCK)失败\n");
exit(1);
}
sleep(10);
printf("我已经休息10秒钟了\n");
if(sigismember(&newmask, SIGQUIT)) //测试一个指定信号是否被置为1
{
printf("SIGQUIT信号被屏蔽了\n");
}
else
{
printf("SIGQUIT信号没有被屏蔽\n");
}
if(sigprocmask(SIG_SETMASK, &oldmask, NULL)<0)
{
printf("SIGQUIT信号被屏蔽了\n");
exit(1);
}
else
{
printf("SIGQUIT信号没有被屏蔽, 您可以发送SIGQUIT信号了, 我要sleep10秒钟\n");
int mysl = sleep(10);
if (mysl > 0)
{
printf("sleep还没睡够 剩余%d秒\n", mysl);
}
}
printf("再见了!\n");
return 0;
}
//sleep函数可以被打断:
a) 时间到了
b) 来了一个信号 ,使sleep提前结束, 这时返回一个剩余时间
sigaction()函数是用来取代signal的。商业软件中用这个。