信号处理的工作原理:阻塞信号集/未决信号集
未决信号集:
没有被当前进程处理的信号集
阻塞信号集:
将某个信号放到阻塞信号集,这个信号就不会被进程处理
阻塞解除后,信号被处理
---------------------------------------------------------------
信号处理的工作原理:内核PCB中,存放着未决信号集/阻塞信号集
1.当产生信号XXX时,将在[未决信号集]中将XXX信号的标志位设为1
2.放入[未决信号集]中的XXX信号等待处理,在处理之前需要做一件事:判断
[阻塞信号集]中的XXX信号的标志位是否为1(如果为1,不处理XXX信号;如
果为0,处理XXX信号)
信号集函数
int sigemptyset(sigset_t *set); //将set集合置空
int sigfillset(sigset_t *set); //将所有信号加入set集合
int sigaddset(sigset_t *set, int signum); //将signum信号加入set集合
int sigdelset(sigset_t *set, int signum); //从set集合中移除signum信号
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); //将自定义信号集放在内核中的[阻塞信号集]中
参数:
how取值,假设当前的信号屏蔽字为mask
SIG_BLOCK:mask=mask|set 添加屏蔽字
SIG_UNBLOCK:mask=mask|~set 解除屏蔽字
SIG_SETMASK:mask=set
set:传出的新的set
oldset:设置之前的当前的信号屏蔽字集合
使用:sigprocmask(___,&set,NULL);
int sigpending(sigset_t *set); //读取当前进程的未决信号集sigpendset
int sigismember(const sigset_t *set, int signum); //判断set集合中是否存在signum信号
案例1:[获取]当前进程的未决信号集
int main(){
//每隔1s获取一次内存的未决信号集
while(1){
sigset_t pendset;
sigpending(&pendset); //获取[当前进程]的未决信号集,存放在pendset集合中
//1-31信号
for(int i=1;i<=31;i++){
//判断信号i是否在pendset中,
if(sigismember(&pendset,i))
printf("1");
else
printf("0");
}
printf("\n");
sleep(1);
}
return 0;
}
[gjw@localhost 4-signal]$ ./signal_set
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
案例2:
int main(){
sigset_t myset;
//清空myset
sigemptyset(&myset);
//将下面三个信号添加到myset集合中
sigaddset(&myset,SIGINT); /* ctrl+C */
sigaddset(&myset,SIGQUIT);/* ctrl+\ */
sigaddset(&myset,SIGKILL);
//将myset集合中的信号设为[阻塞]
sigprocmask(SIG_BLOCK,&myset,NULL);
while(1){
sigset_t pendset;
sigpending(&pendset); //读取当前进程的未决信号集
//1-31
for(int i=1;i<=31;i++){
if(sigismember(&pendset,i)) //判断i信号是否在penset中
printf("1");
else
printf("0");
}
printf("\n");
sleep(1);
}
return 0;
}
[gjw@localhost 4-signal]$ ./signal_set
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
^C0100000000000000000000000000000 #点击ctrl+C
^\0110000000000000000000000000000 #点击ctrl+\
0110000000000000000000000000000
0110000000000000000000000000000
0110000000000000000000000000000
已杀死 #kill -9 signal_set的pid
程序解读:
1.将ctrl+C,ctrl+\,kill -9引发的信号,放入myset阻塞信号集中
2.调用ctrl+C,ctrl+\触发相应的信号,调用sigpending函数获取[当前进程的
未决信号集],存放在pendset集合中
3.for循环,使用sigismember函数判断i信号是否在pendset集合中
4.调用kill -9杀死当前进程