Linux信号补充——信号捕捉处理

一、信号的捕捉处理

​ 信号保存后会在合适的时间进行处理;

1.1信号处理时间

​ 进程会在操作系统的调度下处理信号,操作系统只管发信号,即信号处理是由进程完成的

​ 1.信号处理首先进程得检查是否有信号;2.进程要处于内核状态才能处理信号;

即进程会在内核态返回用户态的时候检查并处理信号

在这里插入图片描述

​ 对于程序的执行有一部分是自己写的,有一部分是库提供的,还有一部分是操作系统提供的;执行操作系统提供的代码需要进行身份的切换,执行自己写的和库提供的一般是以用户态的身份执行,执行系统调用,或者是进入操作系统内部(如硬件中断,根据中断号执行内核的终端表方法)需要以内核态的身份进行;

​ 操作系统可以响应外部硬件的中断,也可以响应内部软件产生的中断;int 80(是一条汇编也是CPU可以认识的指令)就是一种软件中断,功能是让进程从用户态陷入内核态;

​ 总结:程序运行时,会从代码区开始执行,执行到函数调用时触发int 80将ecs后两位由11变成00,进入内核态,根据用户级页表映射进入内核空间执行代码,根据内核级页表映射到内存空间,执行代码,返回时要先执行一次do signal(当前进程对信号做一次检测,对pending表,block表的检测),如果不需要处理,直接变成用户态,将ecs寄存器的后两位由00变成11,并且返回到原先用户空间执行代码处;否则先将pending表对应信号位置零,对于忽略方式直接返回,默认方式直接执行,都是在内核空间处理,而对于自定义处理需要先将身份转换为用户态(因为操作系统不信任用户的代码,有风险)然后执行完使用sigreturn(使用函数压栈的方式传入的此函数,所以可以执行)返回内核态跳转之前的位置,然后在跳转回用户态执行的地方;

​ 要注意main和sighandler是两个不同的执行流不是调用和被调用的关系;

在这里插入图片描述

​ 对于自定义信号处理进行了4次身份切换,两次信号的检测,而默认和忽略方式处理信号只是进行了2次身份切换,1次信号检测;

​ 由于进程是会被调度的,进程上下文的恢复和进程调度的实现都是在内核空间的,所以一定会由频繁的身份切换,所以一定会对信号进行检测;

1.2信号处理接口

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
//既可以处理普通信号也可以处理实时信号
struct sigaction {void     (*sa_handler)(int);void     (*sa_sigaction)(int, siginfo_t *, void *);//不关心,处理实时信号sigset_t   sa_mask;//,除了当前信号自动屏蔽,还可以选择将多个信号屏蔽int        sa_flags;//不关心,默认设为0void     (*sa_restorer)(void);//不关心
};
//与signal使用类似只不过需要传入结构体对象;

​ 信号处理前会先将pending位图对应位置的1置为0;

​ 当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字,这样就保证了在处理某个信号时,如果这种信号再次产生,那么 它会被阻塞到当前处理结束为止。 如果在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字。

上述方式可以防止信号捕捉函数被重复调用

二、补充话题

2.1可重入函数

​ 当头插节点时,有三个位置newnode1,prev,cur三个节点指针,刚完成刚完成newnode1和cur节点的链接,还没有执行prev和newnode1的链接,因为信号的处理跳转到新的执行流,刚好信号处理也是头插,使用的是newnode2,这次执行是完整的,返回用户态是继续执行会将指向newnode2的prev指向了newnode1,这样会导致newnode2丢失导致内存泄漏;

​ 如上现象就是函数被重入了,对于函数如果重入了出错,则该函数就是不可重入函数,反之就是可重入函数;

​ 信号处理和main执行流并不是和多线程一样一旦创建线程执行流就开始运行,并且和main执行流是并行的,而是取决于信号并且执行信号流时会使得main执行流被暂停,是一个进程的不同执行流;

2.2volatile

​ volatile作用是保持内存可见性;进行运算(算术运算或者逻辑运算),都会进入CPU的运算器进行;

​ 在优化条件下如果只是对变量读取不进行修改,可能变量会被优化到寄存器里面,而不是内存中,这样优化是的不需要进行访存,提高了效率;

​ 如:设置全局变量,main执行流只是进行了读取,而信号执行流进行了写入,这时候编译器优化,main执行流不从内存中读取,而是从寄存器读取,但是寄存器中的内容并不会被修改,信号执行流进行了写入,内存中实实在在的被修改了;这时候就会导致全局变量即使被修改了,但是main在执行流不可见;所以需要在全局变量前加volatile关键字修饰,保持内存的可见性,使得main执行流从内存中进行读取;

register是一个建议性关键字用来进行优化,还是会创建变量,但是可能会将变量内容放到寄存器;

2.2.1Linux gcc/g++优化

gcc -O .c文件
#选项包括-O0到-O3;0表示没有优化,1-3从低到高进行优化;

2.3SIGCHID

​ 子进程退出时,父进程必须进行等待,否则子进程就会变成僵尸状态;

​ 等待的目的:1.使得子进程可以被回收;2.获得子进程的退出信息;3.由于子进程的退出是未知的,所以父进程需要阻塞或者是非阻塞的方式进行等待,要保证父进程是最后一个退出的;

子进程并不是直接就退出了,而是会向父进程发送信号的;此信号就叫做SIGCHID(17号)信号

​ 进程等待可以采用基于信号的方式实现异步等待;要保证父进程在这期间是一直运行的;

​ 使用waitpid非阻塞的方式或者是基于信号的等待都可以使得父进程继续运行,不用阻塞;

​ 关于多个子进程等待,使用-1来接受任意多个子进程,使用WNOHANG防止等待时,有进程不退出导致阻塞;

​ 对于信号实现子进程的等待也可以不调用waitpid;事实上,由于UNIX的历史原因,要想不产生僵尸进程还有另外一种办法:父进程调用sigaction将SIGCHLD的处理动作置为SIG_IGN,这样fork出来的子进程在终止时会自动清理掉,不会产生僵尸进程,也不会通知父进程。系统默认的忽略动作和用户用sigaction函数自定义的忽略通常是没有区别的,但这是一个特例。此方法对于Linux可用,但不保证在其它UNIX系统上都可用;

​ 17号信号的默认处理方式是忽略,而忽略方式是自动清理子进程;

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

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

相关文章

麒麟V10环境部署Docker、JDK以及基础环境配置

麒麟V10环境部署Docker以及JDK 挂载“Windows”下共享目录到虚拟机 # 配置 SHARE_REMOTE_PATH=//192.168.2.10/F SHARE_REMOTE_USR=smb SHARE_REMOTE_PWD=smb SHARE_LOCAL_PATH=/mnt/f# 挂载 mkdir ${SHARE_LOCAL_PATH} sudo mount -t cifs ${SHARE_REMOTE_PATH}

24计算机考研调剂 | 【211】太原理工大学

太原理工大学&#xff08;211&#xff0c;双一流&#xff09;冰雪环境智能检测与应用团队招收2024年调剂研究生 考研调剂招生信息 学校:太原理工 专业:理学->物理学 工学->仪器科学与技术->光学工程 工学->工程[专]->集成电路工程 工学->工程[专]->仪器…

赋能智能未来:AI大模型的学习之旅

随着人工智能的迅速发展&#xff0c;AI大模型已经成为技术领域的一个热点。这些模型以其强大的数据处理能力和预测精度&#xff0c;正在不断推动着科技的边界&#xff0c;并且在医疗、金融、交通等多个行业中显示出了巨大的潜力。然而&#xff0c;构建和训练一个高效的AI大模型…

PCL 点云L1中值收缩(论文复现)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 这个方法的大致过程如下所述: 1、从未定向的原始点云扫描中随机采样一组点,并将每个点迭代地投影和重新分布到其局部邻域内的输入点的中心。 2、在这个迭代过程中,通过逐渐增加邻域的大小来处理不同细节级别的结…

浅谈如何自我实现一个消息队列服务器(2)——实现 broker server 服务器

文章目录 一、实现 broker server 服务器1.1 创建一个SpringBoot项目1.2 创建Java类 二、硬盘持久化存储 broker server 里的数据2.1 数据库存储2.1.1 浅谈SQLiteMyBatis 2.1.2 如何使用SQLite 2.2 使用DataBaseManager类封装数据库操作2.3 文件存储消息2.3.1 存储消息时&#…

宏景eHR report_org_collect_tree.jsp SQL注入漏洞复现

0x01 产品简介 宏景eHR人力资源管理软件是一款人力资源管理与数字化应用相融合,满足动态化、协同化、流程化、战略化需求的软件。 0x02 漏洞概述 宏景eHR report_org_collect_tree.jsp 接口处存在SQL注入漏洞,未经过身份认证的远程攻击者可利用此漏洞执行任意SQL指令,从而…

Docker部署Alist全平台网盘神器结合内网穿透实现无公网IP访问云盘资源

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-oZuxWTWUiXLx3aQO {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

SpringBoot实战(二十七)集成WebFlux

目录 一、WebFlux1.1 定义1.2 WebFlux 与 Spring MVC 区别 二、代码实现2.1 Maven 配置2.2 暴露 RESTful API 接口的方式方式一&#xff1a;基于注解的控制器方式二&#xff1a;函数式路由器&#xff08;Functional Endpoints&#xff09; 2.3 测试Service2.4 测试ServiceImpl2…

Streamlit实战手册:从数据应用到机器学习模型部署

Streamlit实战手册&#xff1a;从数据应用到机器学习模型部署 简介Streamlit核心功能介绍Streamlit的安装创建第一个Streamlit应用界面布局与导航数据处理与展示 Streamlit的进阶应用交互式组件按钮复选框单选按钮滑块 图表与可视化使用Matplotlib绘图使用Plotly创建交互式图表…

【题目】【网络系统管理】2019年全国职业技能大赛高职组计算机网络应用赛项H卷

极安云科专注职业教育技能竞赛培训4年&#xff0c;包含信息安全管理与评估、网络系统管理、网络搭建等多个赛项及各大CTF模块培训学习服务。本团队基于赛项知识点&#xff0c;提供完整全面的系统性理论教学与技能培训&#xff0c;成立至今持续优化教学资源与讲师结构&#xff0…

Springboot 整合 Knife4j (API文档生成工具)

目录 一、Knife4j 介绍 二、Springboot 整合 Knife4j 1、pom.xml中引入依赖包 2、在application.yml 中添加 Knife4j 相关配置 3、打开 Knife4j UI界面 三、关于Knife4j框架中常用的注解 1、Api 2、ApiOperation ​3、ApiOperationSupport(order X) ​4、ApiImplici…

Leetcode 994. 腐烂的橘子

心路历程&#xff1a; 一开始以为和刚做过的岛屿问题很像&#xff0c;只不过是把岛屿问题换成BFS去做&#xff0c;然后再加上一些计数的规则。结果做完后发现只能通过一半左右的测试用例&#xff0c;发现有一个逻辑错误在于&#xff0c;当腐烂的橘子位于两端时&#xff0c;可以…

课时71:流程控制_for循环_综合案例

2.4.5 综合案例 学习目标 这一节&#xff0c;我们从 信息收集、其他实践、小结 三个方面来学习。 信息收集 案例需求 根据提示信息&#xff0c;选择输出 cpu 或者 内存信息。脚本实践-采集系统负载信息 查看脚本内容 [rootlocalhost ~]# cat systemctl_load.sh #!/bin/bas…

C#探索之路基础篇(2):接口Interface的概念、实现、应用范围

文章目录 1 概念2 示例代码&#xff1a;2.1 简单接口的实现2.2 简单的使用接口2.3 使用接口呈现多态性2.4 通过接口实现一个数组迭代器2.5 通过接口来实现松耦合的关系2.6 使用接口实现可扩展、便利性 3 使用范围与时机4 注意事项 不知道大家在学习的过程中&#xff0c;有没有反…

基于Springboot的个人博客系统的设计与实现

目录 1. 第5章 数据库设计 1.1. 数据库概念设计 1.1.1. 用户信息实体 1.1.2. 文章信息实体 1.1.3. 评论信息实体 1.1.4. 附件信息实体 1.1.5. 类别信息实体 1.1.6. 日志信息实体 1.2. 数据库表结构设计 基于Springboot的个人博客系统的设计与实现 第5章 数据库设计 …

笔试总结01

1、spring原理 1、spring原理 spring的最大作用ioc/di,将类与类的依赖关系写在配置文件中&#xff0c;程序在运行时根据配置文件动态加载依赖的类&#xff0c;降低的类与类之间的藕合度。它的原理是在applicationContext.xml加入bean标记,在bean标记中通过class属性说明具体类…

148 Linux 网络编程4 ,高并发服务器 --多路I/O转接服务器 - poll 这个非重点,

Poll 的实现和 select 很像。 实际上poll 的核心就是我们select的优化版本&#xff0c;加入了一个数组&#xff0c; 还将传入传出参数分离开了 #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);fds &#xff1a;需要监听的--文件描述符数组…

数据挖掘|数据集成|基于Python的数据集成关键问题处理

数据挖掘|数据集成|基于Python的数据集成关键问题处理 1. 实体识别2. 数据冗余与相关性分析3. 去除重复记录4. 数据值冲突的检测与处理5. 基于Python的数据集成5.1 merge()方法5.2 Concat()方法 数据集成是把来自多个数据库或文件等不同数据源的数据整合成一致的数据存储。其中…

基于docker创建深度学习开发环境

基于docker创建深度学习开发环境 记录几个链接 第一步&#xff1a;配置docker环境&#xff0c;此处大把教程&#xff0c;不再赘述第二步&#xff1a;拉取nvidia做好的cuda和cudnn镜像&#xff1a; docker pull nvcr.io/nvidia/cuda:12.2.0-devel-ubuntu20.04如果有其他需求&a…

vue3+threejs新手从零开发卡牌游戏(二):初始化场景

在删掉初始化中一些没用的代码后&#xff0c;在views目录下新建game文件夹&#xff0c;在里面新建一个index.vue&#xff0c;这里就当成游戏的主入口。 目录结构如下&#xff1a; 下面开始尝试创建场景&#xff1a; 一、添加一个div作为threejs的画布对象&#xff0c;之后整个…