linux 之信号集处理函数

屏蔽信号集

用于屏蔽某些信号。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信号,收到该信号就能立即处理,然后层层返回。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值