sigaction 信号捕捉
它也是信号捕捉,不仅能处理普通信号还能处理实时信号,但我们不管实时信号
我们发现函数名和形参中结构体名一样都是sigaction,这在c/c++中允许吗?
不建议,但是可以
signo你要捕捉几号信号
输入型参数act结构体里面包含了你要设置新的动作,输出型参数oact是保存老的设置以便你后续恢复
看看sigaction结构体里面,红线是我们不关心的,里面有个sa_handler不就是之前信号捕捉的函数指针类型吗,也就是处理方法,其实也就是修改了handler表里面的方法
这个结构体红线你都不关心,那直接用memset都清零就可以
问题
1、结构体中sa_mask什么鬼?
2、如果要处理一个信号了,进程的pending位图里面对应信号是1,这个1是在信号处理前清零还是信号处理后清零?
你都能捕捉了,你在捕捉里面打印看看Pending表就知道了,如果信号处理方法中打印出来2号信号是0那么说明在信号处理前pending中信号就已经被清零了
所以结论:pending位图,什么时候从1->0. 执行信号捕捉方法之前,先清0,在调用
一个事实:当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来
的信号屏蔽字,这样就保证了在处理某个信号时,如果这种信号再次产生,那么 它会被阻塞到当前处理结束为止
也就说不允许同一个信号不断向我的进程发,让我进程不断忙于各种信号处理
如果没有这个事实的话
在信号捕捉方法中,也就是自定义动作函数中:
1.函数中可以陷入内核,因为函数中会被调度 或者 系统调用,而且这很正常我调个printf访问硬件你不给我系统调用吗
2.如果再来一个2号信号,这是可以的因为你处理前就把pending表2号由1变0,所以正在处理2号信号还能再接收2号信号
所以此时很尴尬我们正在对2号进行捕捉,又来一个2号信号,又陷入方法函数中继续再进行捕捉
相当于对handler方法不断的重复调用,如果一直这么调用那连信号捕捉我还返回不了了!
OS不允许你这么干。
那怎么证明信号捕捉时,2号信号确实是被屏蔽了呢?
我们让捕捉函数中死循环打印pending表,一直处理2号信号,此时我们在发送一次2号信号,如果被屏蔽就会看到2号信号由0置1
证明完成
所以OS不允许对同一种信号进行不断嵌套式的捕捉,它的捕捉层数只能是一层,任何一个信号都是如此
所以struct sigaction结构体中sa_mask是干什么的呢?
如果在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需
要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字。
正在处理2号信号期间只有2号会被自动屏蔽。
如果我还想屏蔽更多信号呢?? ?那就利用这个sa_mask设置
最后说一下
所以处理一个信号期间,如果我再收到10个同样的信号,最终这个信号只会被记录一次,因为只有一个pending位图哦