屏蔽信号集
用于屏蔽某些信号。64位位图。
进程接收到某个信号号,回去查看这个信号集,若信号未被屏蔽,那么进程就能马上去处理这些信号
- 手动,调用信号集api函数去设置
- 自动,进程在处理某信号时,可能会屏蔽它接收到的其他信号,处理完当前信号再去处理这些信号
未处理信号集
信号如果被屏蔽,则记录在未处理信号集中,屏蔽信号解除以后,进程才能提取这些信号进行处理。
- 非实时信号(1 ~ 31),不排队,只留一个
- 实时信号(34 ~ 64),保留全部
测试代码
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
void my_func(int signo)
{
printf("Hello\n");
sleep(5);
printf("World.\n");
}
int main()
{
signal(SIGINT,my_func);
while(1);
return 0;
}
编译与测试
jl@jl-virtual-machine:~/test/11_3$ gcc signal_mask.c -o signal_mask
jl@jl-virtual-machine:~/test/11_3$
jl@jl-virtual-machine:~/test/11_3$
jl@jl-virtual-machine:~/test/11_3$ ls
signal_mask signal_mask.c
jl@jl-virtual-machine:~/test/11_3$
jl@jl-virtual-machine:~/test/11_3$
jl@jl-virtual-machine:~/test/11_3$ ./signal_mask
^CHello
World.
^CHello
^C^C^C^C^C^CWorld. <----接收到多个SIGINT信号,但都被屏蔽,只保留一个,处理完再处理这一个
Hello
World.
^\Quit (core dumped)
jl@jl-virtual-machine:~/test/11_3$
可以看到,对于SIGINT 这个信号,进程在信号处理的过程中,再次接收到此种信号也会屏蔽,多次接收到这个信号也只保留一个。可见 SIGINT 是非实时信号
信号集相关api
把我们自己设置的信号集作为这四个api的参数,利用这些api来改写信号集。
int sigemptyset(sigset_t *set);
----->将信号集合初始化为0
int sigfillset(sigset_t *set);
----->将信号集合初始化为1
int sigaddset(sigset_t *set,int signum);
----->将信号集合某一位设置成1
int sigdelset(sigset_t *set,int signum);
----->将信号集合某一位设置为0
int sigprocmask(int how,const sigset_t *set,sigset_t *oldset);
------>使用设置好的信号集去修改屏蔽信号集
参数 how
SIG_BLOCK:屏蔽某个信号(屏蔽集 | set)
SIG_UNBLOCK:打开某个信号(屏蔽集 & (~ set))
SIG_SETMASK:屏蔽集 = set
参数 oldset
保存旧的屏蔽集的值,NULL表示不保存
测试代码
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
void my_func(int signo)
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set,SIGINT);
sigprocmask(SIG_UNBLOCK,&set,NULL);
printf("Hello\n");
sleep(5);
printf("World.\n");
}
int main()
{
signal(SIGINT,my_func);
while(1);
return 0;
}
编译验证
jl@jl-virtual-machine:~/test/11_3$
jl@jl-virtual-machine:~/test/11_3$
jl@jl-virtual-machine:~/test/11_3$ ./a.out
^CHello
^CHello
^CHello
^CHello
^CHello
World.
World.
World.
World.
World.
可以看到,在中断处理函数里面,不再屏蔽 SIGINT信号,收到该信号就能立即处理,然后层层返回。