当前位置: 首页 > news >正文

linux信号 | 学习信号四步走 | 透析信号是如何被处理的?

        前言:本节内容讲述linux信号的捕捉。 我们通过前面的学习, 已经学习了信号的概念, 信号的产生, 信号的保存。 只剩下信号的处理。 而信号的处理我们应该着重注意的是第三种处理方式——信号的捕捉。 也就是说, 这篇文章其实最核心的部分就是在解释信号的捕捉。 但是大的篇幅还是在前面的预备知识上面。现在, 开始我们的学习吧!

        ps: 本节内容适合了解信号概念, 信号产生, 信号保存的友友们观看。

目录

信号是什么时候被处理的呢? 

重谈地址空间

操作系统的执行逻辑

cpu与用户态和内核态

捕捉过程


信号是什么时候被处理的呢? 

        我们要处理一个信号, 首先是我们自己知道自己收到信号了。 那么知道自己收到信号了, 进程就必须得在合适的时候查一查我们对应的pending位图, block位图以及handler数组。 而这三个表都属于内核数据结构 进程不会, 也不能直接访问他们。  而解决方法是让进程处于一种内核状态。 当进程从内核态转回用户态的时候就会对信号做检测并处理

        关于内核态用户态, 是我们从学习linux到现在, 第一次听到的名词。一般我们自己进程在进行的时候, cpu进行调度的时候不仅仅运行我们自己写的代码。 比如我们的代码里还有系统调用或者库函数调用。 对应着就是我们自己写的代码, 库自己写的代码, 操作系统曾经写的代码。 ——这些cpu都要跑。 就比如我们进程等待wait函数, 我们创建子进程的fork, 我们打印数据printf。 这些操作我们都没有自己进行, 都是通过系统调用或者库函数直接进行调用。 

        那么, 我们的操作系统既然不相信我们的用户, 所以在很多场景下, 它是需要我们的用户做一下相关的身份切换的, 才允许我们执行对应的代码。 一般我们在执行库函数的时候, 执行我们自己的代码的时候, 一般都是在用户态直接执行的还有一种是进程在cpu调度之下, 要陷入到操作系统内部, 执行对应的任务——最典型的就是在调用系统调用的时候。——这里要知道的是, 当我们调用系统调用的时候, 操作系统会自动把我们的用户的身份进行转变, 转变为内核身份。 然后由操作系统帮我们把函数执行完毕。 当返回时, 再把我们的身份从内核身份转化为用户身份。 此时才能够允许我们执行系统调用。 ——这里我们只需要知道, 系统调用除了调用函数, 也是需要进行身份变换的。 这里的身份就两个, 一个是用户态, 一个是内核态。 
        也就是说, 调用系统调用, 操作系统是自动会做身份切换的。 (从用户到内核, 或者从内核到用户)

重谈地址空间

        我们其实之前学到的进程相关的知识, 其实都是和我们上图中的用户空间相关联(0~3GB), 但是在3~4GB还有一个内核地址空间这个内核地址空间其实映射的就是操作系统的代码和数据。 而且因为操作系统最先被加载进进程的程序, 所以它的代码和数据应该在内存中的较为底部的位置。 同时映射的时候需要有一个内核级页表进行映射。 

        那么这里问题就来了, 如果我们的系统中有很多进程的话, 用户页表有几份呢 ? 内核级页表有几份呢 ?

  •         对于用户级页表: 有几个进程就有几份用户级页表, 因为进程具有独立性。 
  •         对于内核级页表: 有一份。

        所以, 我们的每一个进程, 看到的都是3 ~ 4GB内核空间里面的内容, 看到的内核级页表里面的内容, 看到的物理内存里面的操作系统的代码和数据的内容都是一样的!!

        要知道, 我们的各种系统调用的方法, 比如write, read, wait, fork, sigset_t等等都是在内核空间的。 

        所以, 以后我们进程在代码区进行系统调用的时候, 就直接找自己内核地址空间里面的系统方法然后返回到代码区

        就如同在自己的地址空间里面直接调用

  • ——在进程的视角: 我们调用系统当中的方法, 就是在我们自己的地址空间中进行执行的。        
  • ——在OS的视角: 在任何一个时刻, 都有进程在执行。 我们想执行操作系统的代码, 就可以随时执行。 

操作系统的执行逻辑

        执行逻辑就是——基于时钟中断的一个死循环。 

        在我们计算机里面都有一个芯片单元, 每隔很短很短的时间, 向计算机发送时钟中断 接收到所谓的时钟中断后, 就要执行中断所对应的方法, 也就是操作系统的代码。 也就是说我们的计算机内部有一个芯片单元, 它每隔很短的时间就给cpu发送一次时钟中断, 这个就叫做一次滴答。 然后我们操作系统, 就被动的被时钟中断推着向后执行。 

        然后操作系统将前期的工作做完之后, 往后的过程中就是执行一个死循环, 在死循环中检测有没有时钟到来, 如果有时钟到来, cpu就去执行时钟中断对应的方法。具体的操作系统如何做的, 看下图:

        

这张图里面有些字段已经被博主标记出来了, 但是有些字段涉及的内容太多, 无法全部截图, 所以这里直接叙述:

        首先说这个for(; ;) pause(); 这个是一个死循环,说明操作系统执行到这里后就什么都没干, 一直执行一个pause()pause的意思是暂停, 为什么暂停? 因为操作系统往后的动作, 都靠着时钟中断来驱动, 也就是说, 有外设中断, 操作系统就去执行对应的中断。 

        也就是说, 操作系统最后会卡在for(; ;) pause();  什么都不去做, 一直暂停在这里相应中断。 而我们的操作系统响应中断, 就一直在执行相应的调用。 所以, 我们的硬件一直在推着操作系统在走。 所以, 我们的操作系统才一直推着我们的进程在走。 所以我们的代码才得以推进。 

        ps:我们的计算机天然就有计算时间的能力, 就比如我们的台式电脑即便断电, 再次开机的时间也能够正确。 这是因为计算机内部可以续电, 可能是纽扣电池, 然后我们计算机能够通过一种硬件单元进行时间的计算。 

        然后要着重说一下的就是这个调度程序初始化:

        这个timer_interrupt, 如果没有中断就绪, 就会执行这个。 这个东西是用来相应每隔很小时间发来的中断的, 比如执行或者调度等操作。 

cpu与用户态和内核态

        我们说过, 么一个当前正在调度的进程, 对应的这个进程有自己的页表。 并且, cpu中有一个CR3寄存器, 这个寄存器直接指向当前进程所对应的用户级页表。 

        同时有一个ECS寄存器。 我们怎么知道我们当前是用户态还是内核态呢? 进程如果在执行用户的代码的时候, ECS一定是指向用户态进程如果在执行系统的代码的时候, ECS一定是指向内核态。 关键在于, 在ECS寄存器里面, 最后有着两个比特位。 这两个比特位有四种表示方式:00、01、10、11. linux内核中, 对于cpu常见的有两种工作模式, 一种叫做内核态00, 一种叫做用户态01。 所以如果今天想访问内核态对应的代码, 必须想办法将ECS的低两位由三置为0. 那么谁能做到呢? ——cpu必须给我们提供一个方法, 能够修改自己的工作状态, 即int 80陷入内核。

  •         内核态: 允许访问操作系统的代码和数据。 
  •         用户态: 只能访问用户自己的代码和数据。

捕捉过程

要理解信号的捕捉过程, 我们可以先看下面这张图。     接下来就是对这张图进行解释:

  •         首先, 信号的处理必须是操作系统要先检测到信号。 那么这个检测的时机就是上面图中的红圈圈。 上面这张图是一个循环的, 但是进程的开始要从绿色的位置执行。 然后一开始在用户态, 在用户态执行main函数的时候, 遇到异常或者其他触发信号的调用, 就进入内核态。 也就是经过第一个蓝色圈圈, 到了下层。 然后操作系统就进行检测。 
  •         现在谈一谈这个检测:做检测, 首先要遍历pending列表。 看看有没有信号,再看看有没有block。 没有就正常执行, 有的话就不做处理, 继续看下一个。 直到遇到1, 并且block没有被阻塞就执行信号动作。那么此时如果这个信号是DFL,就是默认动作, 该怎么样就怎么样。 如果是IGN, 就是忽略, 什么都不做。 并且在执行这个信号动作之前将信号的pending由零变成1。 这两种都是直接在内核态执行的。
  •         但是问题来了, 如果不是忽略或者默认, 而是自定义动作呢? ——要知道, 我们的自定义动作是用户代码,执行它就需要进入用户态。 那么我们为什么要使用用户态而不直接使用内核态呢? 因为如果我们调用的是非法代码。 盗取了我们计算机内的重要信息, 此时就会出现危险。 所以我们必须返回用户态。 然后从用户态处理完之后, 就会原路返回, 也就是利用sigreturn系统调用回归内核态, 再利用sys_sigreturn返回main。 
  •         那么进程我们知道是会被调度的, 只要他再跑, cpu就会调度它的进程。 只要需要调度, 时间片必然会消耗完毕。 消耗完毕就必然将时间片从cpu上剥离下来, 当下次调用进程的时候, 必然要把进程的各种队列放到寄存器里面跑, 而这个过程中, 见数据恢复到cpu中的过程一定在内核态, 而开始执行进程代码时一定是在用户态。 所以, 在进程调度的时候, 有无数次机会从进程用户态到内核态, 从内核态到用户态。 

——————以上就是本节全部内容哦, 如果对友友们有帮助的话可以关注博主, 方便学习更多知识哦!!! 

相关文章:

linux信号 | 学习信号四步走 | 透析信号是如何被处理的?

前言:本节内容讲述linux信号的捕捉。 我们通过前面的学习, 已经学习了信号的概念, 信号的产生, 信号的保存。 只剩下信号的处理。 而信号的处理我们应该着重注意的是第三种处理方式——信号的捕捉。 也就是说, 这篇文章…...

mysql语句执行过程

具体流程如下: 1】当客户端的SOL发送到MySQL时,首先是到达服务器层的连接器,连接器会对你此次发起的连接进行权限校验,以此来获取你这个账号拥有的权限。当你的账号或密码不正确时,会报用户错误。连接成功如果后续没有任何操作&am…...

最新版本SkyWalking【10.1.0】部署

这里写目录标题 前言前置条件启动Skywalking下载解压启动说明 集成Skywalking Agent下载Agent在IDEA中添加agent启动应用并访问SpringBoot接口 说明 前言 基于当前最新版10.1.0搭建skywalking 前置条件 装有JDK11版本的环境了解SpringBoot相关知识 启动Skywalking 下载 地…...

WSL2 中配置桥接模式、虚拟交换机及固定 IP

WSL2 中配置桥接模式、虚拟交换机及固定 IP 一、创建虚拟交换机1.1 使用 Hyper-V 管理器创建虚拟交换机1.2 使用 PowerShell 创建虚拟交换机 二、更新 WSL 配置三、设置 WSL2 中的静态 IP、网关和 DNS3.1 编辑网络配置文件3.2 应用网络配置3.3 测试网络连接 四、重启 WSL 在使用…...

Unite Shanghai 2024 团结引擎专场 | 团结引擎 OpenHarmony 工程剖析

在 2024 年 7 月 24 日的 Unite Shanghai 2024 团结引擎专场演讲中,Unity中国 OpenHarmony 技术负责人刘伟贤对团结引擎导出的 OpenHarmony 工程进行了细节剖析,详细讲解 XComponent 如何与引擎结合,UI 线程和引擎线程的关联以及 ts/ets 的代…...

计算机毕业设计 基于Hadoop的智慧校园数据共享平台的设计与实现 Python毕业设计 Python毕业设计选题 Spark 大数据【附源码+安装调试】

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...

2022CCPC绵阳站VP题解报告(CGHMAE六题)

文章目录 2022CCPC绵阳站VP题解报告前言[Problem - C ](https://codeforces.com/gym/104065/problem/C) (签到思维)[H (codeforces.com)](https://codeforces.com/gym/104065/problem/H) (签到构造)[Problem - G ](https://codefo…...

代码随想录day23:贪心part1

455. 分发饼干 class Solution {public int findContentChildren(int[] g, int[] s) {Arrays.sort(g);Arrays.sort(s);int res 0;int index s.length - 1;for(int i g.length - 1; i > 0; i--){if(index > 0 && s[index] > g[i]){res;index--;}}return r…...

通过网页设置参数,submit还是json

在通过网页设置参数并发送到服务器时,选择使用submit(通常是通过HTML表单的提交)还是直接发送JSON数据(通常是通过AJAX请求,如使用fetch API)取决于几个因素,包括你的服务器端如何处理这些请求、…...

C语言 | Leetcode C语言题解之第463题岛屿的周长

题目&#xff1a; 题解&#xff1a; const int dx[4] {0, 1, 0, -1}; const int dy[4] {1, 0, -1, 0};int dfs(int x, int y, int** grid, int n, int m) {if (x < 0 || x > n || y < 0 || y > m || grid[x][y] 0) {return 1;}if (grid[x][y] 2) {return 0;}g…...

逼近理论及应用精解【12】

文章目录 卷积卷积层与滤波层定义数学原理与公式定理架构例子例题 卷积层和滤波层概念的详细解释卷积层滤波层 滤波层和卷积层在卷积神经网络&#xff08;CNN&#xff09;中区别滤波层卷积层总结卷积层的数学原理滤波层的数学原理 参考文献 卷积 卷积层与滤波层 定义 卷积层…...

LIN总线学习大全(基于CANoe和CAPL)

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…...

国庆作业

day1 1.开发环境 Linux系统GCCFDBmakefilesqlite3 2.功能描述 项目功能: 服务器&#xff1a;处理客户端的请求&#xff0c;并将数据存入数据库中&#xff0c;客户端请求的数据从数据库进行获取&#xff0c;服务器转发给客户端。 用户客户端&#xff1a;实现账号的注册、登…...

Android OpenGLES2.0开发(四):矩阵变换和相机投影

事物的本质是事物本身所固有的、深藏于‌现象背后并决定或支配现象的方面‌。 还记得我们上一篇绘制的三角形吗&#xff0c;我们确实能够顺利用OpenGL ES绘制出图形了&#xff0c;这是一个好的开始&#xff0c;但这还远远不够。我们定义的坐标是正三角形&#xff0c;但是绘制出…...

快递查询软件:实现单号识别与批量物流查询的高效工具

随着网络购物的普及&#xff0c;快递物流行业迎来了前所未有的发展机遇&#xff0c;同时也面临着巨大的挑战。跟踪物流信息成为一个难题&#xff0c;因此&#xff0c;快递查询软件的核心功能之一便是单号识别。传统的快递单号输入方式繁琐且易出错在此背景下&#xff0c;快递查…...

nodejs与npm版本对应表

Node.js — Node.js 版本 (nodejs.org)...

Spring Boot 项目中如何使用异步任务

前置知识&#xff1a; 同步任务&#xff1a; 同步任务是在单线程中按顺序执行&#xff0c;每次只有一个任务在执行&#xff0c;不会引发线程安全和数据一致性等并发问题 同步任务需要等待任务执行完成后才能执行下一个任务&#xff0c;无法同时处理多个任务&#xff0c;响应慢…...

Scrum实战中遇到的问题与解决方法

在当今快速变化的技术环境中&#xff0c;IT企业面临着持续的市场压力和竞争&#xff0c;传统的瀑布式开发模式已经难以满足现代企业的需要。瀑布模型过于僵化&#xff0c;缺乏灵活性&#xff0c;导致项目经常延期&#xff0c;成本增加&#xff0c;最终可能无法达到预期效果。为…...

全面介绍 Windows 录屏工具:开启录制新篇章

高质量的录屏工具是我们录屏的得力助手。但是日常因为侧重点的不同&#xff0c;比如有的喜欢录制游戏画面、有的需要录制教学视频、演示操作也需要录屏工具。这次我们就来探讨一下windows录屏工具有哪些吧。 1.福晰录屏大师 链接&#xff1a;www.foxitsoftware.cn/REC/ 从这…...

Maven 和 NetBeans:集成与使用

Maven 和 NetBeans:集成与使用 Maven 和 NetBeans 是两款强大的工具,常用于Java开发。Maven是一个项目管理工具,它能够帮助管理项目的构建、报告和文档。NetBeans是一个集成开发环境(IDE),它为Java开发提供了丰富的功能和友好的用户界面。将Maven集成到NetBeans中,可以…...

【系统架构设计师】目录提纲

一、绪论&#xff08;TODO&#xff09; 二、计算机与网络基础知识&#xff08;TODO&#xff09; 三、信息系统基础知识&#xff08;TODO&#xff09; 四、系统开发基础知识&#xff08;TODO&#xff09; 五、软件架构设计&#xff08;TODO&#xff09; 六、UML建模与架构文…...

【微服务】—SpringBoot入门

⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记仓库&#x1f449;https://github.com/A-BigTree/tree-learning-notes 个人主页&#x1f449;https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 文章目录 1 SpringBoot快速入门1.1 SpringBoot简介1.1.1 简介1.1.2…...

Linux: debug: perf: report: --sort

文章目录 简介实例简介 接上回:https://mzhan017.blog.csdn.net/article/details/142689870。 这里介绍perf的这个参数,还是非常的有用,尤其是分析对整个系统做perf record的数据,而不是单个进程做perf record。-s, --sort= : Sort histogram entries by given key(s) - …...

like 模糊查询的底层算法

like 模糊查询的底层算法 全文搜索算法、模糊查询、n-gram分隔算法功能介绍 百度搜索&#xff0c;文心一言给出的结果&#xff1a; SQL模糊查询底层通常使用全文搜索算法&#xff0c;如LIKE操作符和全文索引通常使用的n-gram分割算法。 n-gram是一种将文本分割成固定大小的词…...

【Linux实践】实验九:Shell流程控制语句

文章目录 实验九&#xff1a;Shell流程控制语句实验目的&#xff1a;实验内容&#xff1a;操作步骤&#xff1a;1. 复制*.c文件并排序2. 计算1-10的平方 实验九&#xff1a;Shell流程控制语句 实验目的&#xff1a; 掌握条件判断语句&#xff0c;如if语句、case语句。掌握循环…...

YOLOv8实战TT100K中国交通标志检测【数据集+YOLOv8模型+源码+PyQt5界面】

YOLOv8实战TT100k交通标志识别 文章目录 研究背景资源获取1.前言1.1 YOLO 系列&#xff1a;中国交通标志检测领域的璀璨明星1.2 Transformer与注意力机制&#xff1a;为中国交通标志检测注入新活力1.3 中国交通标志检测技术&#xff1a;迎接挑战&#xff0c;砥砺前行1.4 YOLOv8…...

SQLite3

文章目录 SQLite3 C/CAPI介绍SQLite3 C/C API 使⽤ SQLite3 C/CAPI介绍 C/C API是SQLite3数据库的⼀个客⼾端&#xff0c;提供⼀种⽤C/C操作数据库的⽅法。 SQLite3 C/C API 使⽤ 下⾯我们将这⼏个接⼝封装成⼀个类&#xff0c;快速上⼿这⼏个接口 创建/打开数据库文件针对打开…...

我的创作纪念日一年

目录 机缘 收获 日常 成就 憧憬 机缘 我之所以开始写CSDN博客&#xff0c;源于一段特殊的时光。去年此时&#xff0c;我独自待在实验室&#xff0c;周围的世界仿佛与我无关。没有旅游&#xff0c;没有与朋友的欢聚&#xff0c;情感的挫折和学业的压力如潮水般袭来。在这样的…...

Docker基本操作命令(一)

Docker 是一个开源的应用容器引擎&#xff0c;允许开发者打包应用以及其依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口。主要功能是为开发者提供一个简单…...

PGMP-02项目集管理绩效域

目录 1.概要 2.defintions定义 3.Program Management Performance Domain interactions 交互 4. Organizational Strategy, Portfolio Management, and Program Management Linkage 5. Portfolio and Program Distinctions 区别 6. Program and Project Distinctions区别 …...