信号的捕捉

news2024/11/13 14:56:05

1.信号的产生
信号递达:实际执行信号的处理动作称为信号的递达
信号未决:信号从产生到递达之间的状态
进程可以阻塞某个信号
被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作
注意,忽略和阻塞是不同的,只要信号阻塞就不会被递达,而忽略是递达之后可选的一种处理动作
在这里插入图片描述pending表:用来存放接收到的信号,操作系统向进程发送信号时,都会修改pending表中对应编号处的比特位
block表:用来存放被阻塞的信号,当指定信号需要被阻塞时,操作系统会修改block表中对应编号处的比特位。
handler表:这是是一个数组,用来存放不同信号的处理方法,保存的是函数指针。
比特位的位置:表示信号的编号
比特位的内容:表示是否对特定的信号进行屏蔽(阻塞)
block pending handler
0 0 SIG_DFL
block为0,没有阻塞1号信号
pending为0,没有收到1号信号
handler为SIG_DFL,对1号信号默认的处理方式为SIG_DFL
信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志
2.sigset_t
未决和阻塞可以用相同的数据类型sigset_t来存储,sigset_t 称为信号集,这个类型可以表示每个信号的"有效"或"无效"状态,在阻塞信号集中"有效"和"无效“的含义是该信号是否被阻塞,在未决信号集中"有效"和"无效"的含义是该信号是否处于未决状态。
3.信号集操作函数
int sigemptyset(sigset_tset)
函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号
int sigfillset(sigset_t
set)
函数sigfillset初始化set所指向的信号集,使其中所有信号的对应bit置位,表示该信号集的有效信号包括系统支持的所有信号、
在使用sigset_t 类型的变量之前,一定要调用sigemptyset或者sigfillset做初始化,使信号集处于确定的状态。初始化sigset_t 变量之后就可以再调用sigaddset和sigdelset在该信号集中添加或删除某种有效信号
int sigaddset(sigset_tset)
int sigdelset(sigset_t
set,int signo)
int sigdelset(sigset_tset,int signo)
int sigismember(const sigset_t
set,int signo) 包含返回1,不包含返回0,出错返回-1

sigprocmask
int sigprocmask(int how,const sigset_t *set,sigset_t *oset);
返回值:若成功为则为0,若出错则为-1
如果oset是非空指针,则读取当前进程的当前信号屏蔽字通过oset参数传出。如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何修改。
SIG_BLOCK set包含了我们希望添加到当前信号屏蔽字的信号,相当于mask=mask|set
SIG_UNBLOCK set包含了我们希望从当前信号屏蔽字中解除阻塞的信号,相当于mask=nask&~set
SIG_SETMASK 设置当前信号屏蔽字为set所指向的值,相当于mask=set

sigpending
读取当前进程的未决信号集,通过set参数传出。调用成功返回0,出错返回-1

4.用户级页表和内核级页表
在这里插入图片描述
用户态:正在执行用户层的代码,此时CPU的状态是用户态。
内核态:正在通过系统调用访问内核或者硬件资源时,此时CPU的状态是内核态。
操作系统是怎么知道当前进程的身份状态的呢?
在这里插入图片描述

CR3寄存器:专门用来表征当前进程的运行级别的。
0:表示内核态,此时访问的是内核资源或者硬件。
3:表示用户态,此时执行的是用户层的代码。
在这里插入图片描述我们之前一直所说的页表都是用户级页表,每个进程都有一个。
进程地址空间的大小一共有4GB,我们之前谈论的只有0~3GB,这3GB的空间属于用户空间,用来存放用户的代码,数据等。为了保证进程的独立性,每个进程都有一个进程地址空间,都有一个用户级页表。
还有一共内核级页表,所有进程共用一份。
进程地址空间中的3~4GB空间,是不允许用户访问的,因为这1GB空间中的数据等,通过内核级页表和内存中的操作系统相映射,属于内核级别的。因为内存中只存在一份内核,所以所有进程的虚拟地址空间的这1GB空间都通过同一份内核级页表和内存中的内核相映射。

每一个进程地址空间中的3~4GB的内容都是一样的,因为它们都通过同一个内核级页表和内存映射。

动态链接是通过代码段的位置无关码跳转到共享区从内存中映射过来的动态库来执行相应的方法
系统调用是:
①.当执行到代码段中的系统调用时,会在跳转到当前进程虚拟地址空间中的内核空间中。
②.系统调用的具体实现都放在这1GB的内核空间中。
③.然后根据内核级页表和内存中内核的映射关系实现内核的访问。
为什么我们的代码中不能访问这3~4GB的空间,而系统调用就跳转到这1GB的内核空间中进行访问了呢?
因为从代码段跳转到内核空间中后,CPU中的CR3寄存器从3变成了0。
意味着进程运行级别从用户态变成了内核态,也就是执行者从用户变成了操作系统,所以可以对这1GB的内核空间进行访问。
系统调用接口的起始位置,会将CR3寄存器中的数据从3变成0,完成从用户态向内核态的转变。

5.信号的处理
(如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号)

信号在合适的时候被处理-什么时候?进程从内核态返回到用户态的时候,进行信号的检测和信号的处理

默认处理方式:所有信号的默认处理方式都是结束进程,只是不同信号表示不同的异常。
忽略处理方式:忽略和阻塞不一样,忽略也是一种处理方式,它仅仅是将task_struct中的pending位图中对应信号的比特位清空,然后就直接返回到用户态了。

user mode ①.在执行主控制流程的某条指令时因为中断、异常或系统调用进入内核、
kernel mode ②.内核处理完异常准备回用户模式之前先处理当前进程中可以递送的信号
kernel mode ③.如果信号的处理动作自定义的信号处理函数则回到用户模式执行信号处理函数(而不是回到主控制流程)
(如果不是自定义处理方式,是SIG_DFL和SIG_IGN,以内核态身份进行处理,然后就可以直接返回到用户代码中系统调用的位置,少了两次系统调用)
user mode ④.信号处理函数返回时执行特殊的系统调用sigreturn再次进内核
kernel mode ⑤.返回用户模式从主控制流程中上次被中断的地方继续向下执行

在进程开始运行后,我们在10s内发送了很多次2号信号,但是最终只捕获了两次。
当递达第一个2号信号的时候,同类型的信号无法被递达。
因当前信号在被捕捉的时候,系统会自动将当前信号加入到进程的信号屏蔽字,也就是将block对应的比特位置位,然后将pending表对应比特位清空,再去进行递达。
但是第二个2号信号在第一个信号被捕捉的时候会将对应pending位图的比特位置位。
所以当第一个2号信号处理完毕以后,解除对2号信号的屏蔽后,第二个2号信号就会被递达。
除了这两个2号信号,其余的2号信号都被舍弃了。
注意: 进程处理信号的原则是串行的处理同类型的信号,不允许递归,所以同类型的多个信号同时产生,最多可以处理两个。

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

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

相关文章

【Apache Doris】数据均衡问题排查指南

原文阅读:【巨人肩膀社区博客分享】【Apache Doris】数据均衡问题排查指南 一、前提概要 当集群处于以下几种情况时,可参考本文进行问题排查。 •BE节点之间的数据不均 •单个BE节点上的多个磁盘之间的数据不均 •BE节点的上线和下线进度卡死&#…

《高等代数》两条线行列式

说明:此文章用于本人复习巩固,如果也能帮助到大家那就更加有意义了。 注:两条线行列式的固定做法为按照第一列展开。

Kafka分布式集群部署实战:跨越理论,直击生产环境部署难题与解决方案,性能调优、监控与管理策略大揭秘,轻松上手分布式消息中间件

本文介绍kafka的集群如何部署和安装,1-4章理论知识,第5章详解集群的部署,部署Kafka之前需要先部署好分布式的Zookeeper,不喜欢理论的可以直接看第5章,欢迎大家一起探讨技术! Zookeeper集群部署参考文章&…

VUE-组件间通信(三)全局事件总线

一、作用&#xff1a;任意组件间通信 二、实现 1、创建全局事件总线 new Vue({render: h > h(App),beforeCreate(){//创建全局事件总线Vue.prototype.$busthis} }).$mount(#app) 2、学生组件 触发事件 <template><div class"studentInfo"><h…

(备份)常用ASCII 8*8 点阵 以及查询显示字符的点阵

图片 #include "driver/spi_master.h" #include "driver/gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "string.h" #include "driver/i2c.h" #include "esp_rom_sys.h"…

【postman如何生成python代码】

postman如何生成python代码 https://jingyan.baidu.com/article/86fae3461577c27d48121ad1.html

【大模型系列篇】词向量 - 从Word2Vec到ELMo

&#x1f525;&#x1f525;&#x1f525;首先安利一个比较不错的忍不住就想一键三连的大模型科普: 大模型科普专栏 - AI老兵文哲&#xff08;哔哩哔哩&#xff09; 词向量&#xff08;又叫词嵌入&#xff09;已经成为NLP领域各种任务的必备一步&#xff0c;而且随着BERT、GPT等…

JS打造一款你自己的专用字体:使用p5.js与JavaScript实现

前言 在最近的生成艺术项目中遇到一个小问题&#xff1a;如何在作品中优雅地添加文本元素&#xff0c;同时避免使用网络字体&#xff0c;要么侵权要么花钱~~给项目增加不必要的负担&#xff0c;我决定不走寻常路&#xff0c;自己动手&#xff0c;丰衣足食&#xff0c;用JS打造…

C++11 新特性基础

前言 C11是继&#xff0c;C98/03之后的最大的一次更新&#xff0c;这次更新虽然花了很长的时间&#xff0c;但是真的推出了很多的干货&#xff01;本期内容开始我们将介绍C11常用的操作&#xff01; 目录 前言 一、C11介绍 二、统一的列表初始化 1、{}初始化 2、std::in…

【机器学习】循环神经网络(RNN)介绍

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 循环神经网络(RNN)介绍什么是RNN?RNN的基本原理递归神经网络单元前向传播反向传…

Ubuntu下安装和配置MQTT服务器Mosquitto

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的通信协议&#xff0c;设计用于物联网设备之间的低带宽、不稳定网络环境下的高效通信。MQTT允许设备通过发布&#xff08;publish&#xff09;和订阅&#xff08;subscribe&#xff09;模式进行消…

清华2024内地录取3500人,其中900多人是走这个政策进来的... ...

2024年&#xff0c; 清华大学共录取本科新生3800余人&#xff0c;其中内地学生3500余人&#xff0c;覆盖全国31个省份1000 多所生源中学;港澳台学生60余人&#xff0c;国际学生约230人。 大李露个脸 清华大学2024年新生数据 普通批提前批共录取1549人&#xff0c;占比44% 强基计…

火龙果检测-目标检测数据集(包括VOC格式、YOLO格式)

火龙果检测-目标检测数据集&#xff08;包括VOC格式、YOLO格式&#xff09; 数据集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1NdRBsHnYCK9xZd7bzQoN5w?pwd779l 提取码&#xff1a;779l 数据集信息介绍&#xff1a; 共有 1106 张图像和一一对应的标注文件 标注…

macos OneNote 2016 for Mac 官方pkg下载地址 - macos 10.15 Catalion 可用Onenote版本官方下载地址

macos 10.15 Catalion 版本的系统已经无法正常从应用商店下载到可用的Onenote 应用,原因是版本不受支持, 而且onenote官方链接的应用商店地址https://apps.apple.com/us/app/microsoft-onenote/id784801555?mt12在中国地区也无法访问, 所以中国地区用户如果想使用onenote应用…

【云原生系列之SkyWalking的部署】

1、分布式链路追踪 1.1概念 在较大的web集群和微服务环境中&#xff0c;客户端的一次请求需要经过不同的模块&#xff0c;多个不同中间件&#xff0c;多个不同机器一起相互协作才能处理完成客户端的请求&#xff0c;而在这一系列的请求过程之中,处理流程可能是串行执行,也可能…

华为云征文|基于Flexus云服务器X实例之安装长亭雷池waf教程

&#x1f534;大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 先看这里 写在前面何为长亭雷池waf安装社区版雷池雷池环境要求查看华为云Flexus云服务器X实例的配置一条命令安装雷池waf检查查看是否安装成功 雷池使用登录雷池配置站点 写在…

51单片机.之ADC数字模拟转换

1、数字转模拟电路&#xff0c;输出波形&#xff0c;示波器采集来显示波形 单片机通过i2c给&#xff0c;模数转换器&#xff0c;写入数字信号&#xff0c;定时器1s扫描按键的切换 1、key.c 切换波形 #include <reg52.h>sbit KEY_IN_1 P2^4; sbit KEY_IN_2 P2^5; …

五、Selenium操作指南(一)

文章目录 一、基本用法&#xff08;一&#xff09;初始化浏览器对象&#xff08;二&#xff09;访问页面&#xff08;三&#xff09;设置浏览器大小&#xff08;四&#xff09;刷新页面&#xff08;五&#xff09;前进后退 二、获取页面基础属性三、定位页面元素&#xff08;一…

【QNX+Android虚拟化方案】112 - 获取 88Q5152 Switch Port1、Port2 端口的主从模式 / 传输速率 / 链路状态

【QNX+Android虚拟化方案】112 - 获取 88Q5152 Switch Port1、Port2 端口的主从模式 / 传输速率 / 链路状态 1. 读取 P1、P2 端口 主从模式 / 传输速率2. 读取 P1、P2 端口 Link Status3. 读取 P1、P2 端口 Duplex 全双工/半双工模式4. 读取 P1、P2 链路信号SQI质量5. 完整代码…

基于单片机的肺活量检测仪设计

本设计主要对其中的一种测量方法和原理进行介绍与运用&#xff0c;设计了一款基于STC12C5A60S2单片机的肺活量检测仪&#xff0c;包括供电模块、气流检测模块、按键模块、显示模块、语音输出模块和蓝牙模块&#xff0c;实现对肺活量的数值检测&#xff0c;并对数据进行语音播报…