Linux——sigaction信号捕捉函数

目录

一.sigaction () ;

struct sigaction结构体的成员: 

sigaction()和signal()函数的区别:

二.sigaction函数的使用

        sigaction函数使用案例1: 对该进程发送指定的信号

案例2:对该进程发送多个同类型的信号时:

案例2与案例3的不同之处在于:

三.总结:


一.sigaction () ;

        该函数功能是为信号指定相关的处理程序,但是它在执行信号处理程序时,会把当前信号加入到进程的信号屏蔽字中,从而防止在进行信号处理期间信号丢失。

        该函数的第二三参数类型是一个结构体,act表示指定新的信号处理方式,oldact参数输出先前信号的处理方式(如果不为NULL的话)。

        说白了sigaction函数的作用和之前学过的signal函数的作用一样,全都是针对特定的信号进行信号捕捉,从而进行自定义式的信号处理。

struct sigaction结构体的成员: 

 

sa_handler:   类型是函数指针,该成员和signal的参数handler相同,代表捕获普通信号并对齐做处理的函数;

sa_sigaction:该成员与sa_handler也一样是函数指针,但它用于对实时信号的捕获;

sa_mask:    用来设置在处理该信号时暂时将sa_mask 指定的信号集搁置;
sa_flags:     用来设置信号处理的其他相关操作,下列的数值可用:

        1.SA RESETHAND:当调用信号处理函数时,将信号的处理函数重置为缺省值;

        2.SIG DFLSA RESTART:如果信号中断了进程的某个系统调用,则系统自动启动该系统调用;

        3.SA NODEFER:当信号处理函数运行时,内核将阻塞该给定信号。但是如果设置了 SA NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号。

sa_flags默认情况下赋值0即可。

sigaction()和signal()函数的区别:

      1.signal只能捕获信号,对信号进行处理。但是不能获取信号的其它信息;

      2.sigaction可以使用sigaction结构体的sa_handler函数对信号进行处理(此处等同于signal函数),也可以使用sa_sigactior函数查看信号的各种详细信息;

      3.并且sigaction函数还可以通过sa_mask、sa_flags对信号处理时进行很多其他操作。


二.sigaction函数的使用

        sigaction函数使用案例1: 对该进程发送指定的信号

        代码解析:通过struct sigaction结构体创建对象,利用对象的成员变量为其赋值,对OS发送给该进程的SIGINT2号信号进行信号捕捉。 

 

运行结果:

        专门设置的捕获2号信号,所以我用ctrl+c键向该进程发送2号信号,被sigaction函数捕获,因为sigaction函数的第二参数为新的处理方式newact代替了旧的处理方式oldact,即对象newact的处理方式为自定义方式,调用该对象的成员handler方法。


        每当我发送2号信号,总能被sigaction函数捕获;而当我发送其他信号(例如3号信号)给该进程时,进程收到对3号信号做递达处理,采用默认的递达动作,立即终止进程。 


案例2:对该进程发送多个同类型的信号时:

         代码解析: 当2号信号被进程接收并递达时,因为sigcation函数采用的是自定义方式处理,所以调用handler方法,里面有Count函数,Count函数的作用就是一个倒数10秒的定时器,当2号信号被捕获处理时,10秒后可以完成对信号的处理。相比情况1,代码上只增加了这处。

运行结果:

 
        例:从上面结果右图可知,我向该进程连续发送5次2号信号后,当发送的第一个2号信号被sigcation函数捕获后,它会告知系统让系统将2号信号加入到进程的信号屏蔽字(阻塞位图sa_mask成员),也就是将该进程阻塞位图的第2比特位置1,让第二次及后面向进程发送的2号信号无法递达该进程。当进程递达(自定义)处理完第一个送来的2号信号后,系统又会解除对2号信号的屏蔽,让第二次发送到进程的2号信号能够被进程收到,递达时被捕获,此时,系统又会对阻塞位图的第2比特位进行屏蔽,直到第二次送来的2号信号被进程递达完毕,才会解除对2号信号的屏蔽。
        注意:在上图案例中向进程发送来的5次二号信号中,只有前两次被发送来的2号信号被进程递达处理,剩下的3次都被进程丢弃。原因就是sigcation函数只能对多次发送的同类型信号的前两次进行处理,剩下的均被丢弃。

 

        当右侧窗口在发送五次2号信号一段时间之后,又发送了两次2号信号,情况仍同上面一样,先捕获第一个,屏蔽后面的一个,处理完第一个后,开放第二个2号信号,该2号又被捕获,被进程的handler回调函数处理。 

        


案例3:对该进程发送不同类型的多个信号时,sigaction函数对其他信号的屏蔽:

       代码解析:这段代码上,新增了容器vector,我将想要屏蔽的信号3,4,5存入容器中,当第一个信号:2号被发送且被进程接收处理时,OS会将阻塞位图中的2号和3,4,5号信号都屏蔽掉。

 

       运行解析:对进程连续发送3次2号信号以及两次3号信号,第一个2号信号被进程递达捕获,此时系统将阻塞信号位图中第2、3、4、5位置的比特位置1,那么后面的2、3、4、5号信号都无法被进程递达。等到第一个2号信号递达完毕,系统解除了对2、3、4、5号的阻塞,第2个2号信号被进程捕获处理,同理,当2号信号被处理完毕后,系统又取消了对2、3、4、5号信号的屏蔽因为同类型的多次2号信号中只有前两次能够被处理,第3个2号信号被丢弃,然后紧接着被发送来的第一个3号信号被进程处理,因为sigaction函数没有设置3号信号的捕获,所以进程做默认递达处理,退出进程。

案例2与案例3的不同之处在于:

        案例2与案例3在运行过程中,都向该进程发送了3号信号,但处理的方式并不同。案例2的2号信号仍在被进行自定义捕获处理(10秒内)过程内,OS就向进程发送3号信号,由于没有针对3号信号的捕获,进程立即对3号信号做默认递达处理,在2号信号还没有被递达完毕时,进程就立即自我终止;
        而案例3的2号信号在被进行捕获处理的过程中(10秒内),向进程发送了3号信号,因为sigaddset函数添加过3号信号的原因,在2号信号被捕获处理的一瞬间,系统也就屏蔽阻塞了2号3号的信号,导致进程无法立即对3号信号做默认递达处理,需要等到第2个二号信号被递达处理完毕,进程才能递达处理3号信号,完成默认自我终止。


三.总结:

        所以针对信号发送给进程后,进程对这些信号的各种情况我们都大概理解了,总结出来就是:


        1.当我们对某个进程连续发送多个同类型的信号时,进程处理信号的原则是: 串行处理(一个一个处理)同类型的信号,不允许递归处理。所以在上面情况中,5次发送同类型的2号信号,只有前两次的能被处理,而且还是第一次的处理完,第二次的2号信号才能接着被处理,这就是串行处理。


        2.当进程下递达某一个信号期间,同举型信号无法递达因为同类型的信号已经被系统加入到了进程的信号屏蔽字一一block。


        3.当该信号被递达完毕,系统会解除对同类型信号的屏蔽,进程就会自动进程递达当前的已取消屏蔽的信号。例:当第一个2号信号被进程涕达完毕,系统解除了同举型2号信号的屏蔽,那么第一个2号信号(之前被屏藏、现在肥消屏蔽)会自动被进程递法注:进程只会自动递达这么一个,不会继续自动递达第3次同类型信号,表明了5次中只有前2次能够被处理,剩余的都被丢弃。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/19491.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

github 最简单的使用步骤(个人学习记录~)

github 使用步骤: (11条消息) github新手用法详解(建议收藏!!!)_github详解_怪 咖的博客-CSDN博客 1.获取ssh密钥 打开输入:ssh-keygen -t rsa -C “git账号” 输入之后一路Enter&#xff08…

MySQL自治平台建设的内核原理及实践(下)

本文整理自美团技术沙龙第75期的主题分享《美团数据库攻防演练建设实践》,系超大规模数据库集群保稳系列(内含4个议题的PPT及视频)的第4篇文章。 本文作者在演讲后根据同学们的反馈,补充了很多技术细节,跟演讲&#xf…

使用Vue脚手架2

ref属性 src/components/SchoolName.vue <template><div class"school"><h2>学校名称&#xff1a;{{name}}</h2><h2>学校地址&#xff1a;{{address}}</h2></div> </template><script>export default {name:…

分层解耦-三层架构

三层架构 在上篇文章的案例中写文章-CSDN创作中心 的Controller类承担了对于数据操作&#xff08;访问&#xff09;、对于对于数据的逻辑处理、以及接受请求响应数据的工作&#xff0c;对于类似的小项目来说冗杂程度还可以接收&#xff0c;但是如果项目更加复杂&#xff0c;就…

python3+requests+unittest实战系列【二】

前言&#xff1a;上篇文章python3requestsunittest&#xff1a;接口自动化测试&#xff08;一&#xff09;已经介绍了基于unittest框架的实现接口自动化&#xff0c;但是也存在一些问题&#xff0c;比如最明显的测试数据和业务没有区分开&#xff0c;接口用例不便于管理等&…

快手详情API接口jason格式java php

随着移动互联网的快速发展&#xff0c;短视频应用成为越来越多用户获取信息和进行购物的重要途径。作为广告商或电商平台&#xff0c;了解和充分利用快手的商品详情API接口将为您的营销策略带来巨大的潜力 了解快手商品详情API接口 快手的商品详情API接口是一组提供商品相关信息…

Apache Doris 在金融壹账通指标中台的应用实践

本文导读&#xff1a; 金融壹账通作为中国平安集团的联营公司&#xff0c;依托平安集团 30 多年金融行业的丰富经验及自主科研能力&#xff0c;向客户提供“横向一体化、纵向全覆盖”的整合产品&#xff0c;以“技术业务”为独特竞争力&#xff0c;帮助客户提升效率、提升服务…

6月城市之星领跑活动获奖名单已出炉

经过一个月的角逐&#xff0c;6月城市之星领跑活动上榜名单终于出炉啦&#xff0c;本次城市赛道是根据最后登陆且6月份有入围博客之星用户的城市一共368个城市&#xff0c;城市人数划分区间具体情况如下&#xff1a; 200以上城市2个&#xff0c;其中有一些博主的城市由于未获取…

ArcGIS栅格影像数据处理

ArcGIS栅格影像数据处理 文章目录 ArcGIS栅格影像数据处理1. 栅格影像数据坐标系转换2. 栅格数据16bit转8bit3. 栅格数据波段变换参考链接 1. 栅格影像数据坐标系转换 点击【ArcToolbox】>【数据管理工具】>【投影和变换】>【栅格】>【投影栅格】。 2. 栅格数据16…

Redis---缓存双写一致性

目录 一、什么是缓存双写一致性呢&#xff1f; 1.1 双检加锁机制 二、数据库和缓存一致性的更新策略 2.1、先更新数据库&#xff0c;后更新缓存 2.2 、先更新缓存&#xff0c;后更新数据库 2.3、先删除缓存&#xff0c;在更新数据库 延时双删的策略&#xff1a; 2.4.先更新数…

Linux--操作系统进程的状态

【Linux】进程概念 —— 进程状态_linux d状态进程_Hello_World_213的博客-CSDN博客 新建&#xff1a;字面意思&#xff0c;将你的task_struct创建出来并且还未入队列 运行&#xff1a;task_struct结构体在运行队列中排队&#xff0c;就叫做运行态 阻塞&#xff1a; 等待非C…

Python采集课堂视频教程, m3u8视频解密

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 环境使用: Python 3.8 解释器 Pycharm 编辑器 模块使用&#xff1a; requests >>> pip install requests pycryptodome --> pip install pycryptodome re 第三方模块安装方法&#xff1a; win R 输…