Linux 信号

文章目录

  • 1. 信号
    • 1.1 前言
    • 1.2 信号的位置
    • 1.3 接口
      • 1.3.1 sigset_t
      • 1.3.2 信号集操作接口
      • 1.3.3 signal
      • 1.3.4 sigprocmask
      • 1.3.5 sigpending
  • 2. 信号的处理
    • 2.1 内核态和用户态
    • 2.2 信号的监测和处理

1. 信号

1.1 前言

在 Linux 中,信号是一种用于进程之间的通信机制,通常是异步的,也就是进程随时都可以收到信号,可以通过信号来通知进程发生了什么事,并且进程可以马上对这个信号做出反应和处理

在 Linux 中输入 kill -l可以得到信号的编号以及这些信号大概代表的是什么,常见的比如 9 号信号就是常见的强制杀死进程信号,以及 11 号就是段错误,具体点就是空指针,指针越界这些异常了,还有Ctrl + C 终止信号是 2 号信号。
(注意:信号是从 1 开始的,没有 0 号信号)

在这里插入图片描述虽然总共有 64 个信号,但是前 32 个信号被称为核心信号,现在更关注的也是这前 32 个信号,用的也很频繁,通常用于程序的各种异常问题

1.2 信号的位置

操作系统随时都可能会给进程发送信号,而且还可能连续发送,进程收到信号之后,可能也不会马上处理,手头可能有优先级更高的事,甚至有可能直接忽略这个信号

先来了解一下信号的三种状态

① 递达(Delivery

  • 当进程收到信号之后,就直接执行该信号的处理方法,称为 信号递达,也就是 处理信号

② 未决(Pending

  • 当信号到达的时候,进程不会马上处理这个信号,先放着,称为 未决,即暂时不处理

③ 阻塞 (Block

  • 如果某个信号被设为阻塞,那么进程收到这个信号的时候,会将这个信号置为 未决 状态,并且阻塞如果不取消,这个信号会一直得不到处理

task_struct 中,可以理解成存储了关于 32 个信号对应的 3 个数据结构,这三结构就是 blockpendingdelivery。并且 pendingblock 可以理解为位图

① 比方说,1 号信号在 pending 位图中对应的标志位为 1,那么说明这个信号暂时不被处理,但是当操作系统识别到这个 1 的时候,就会执行相应的处理函数(如果没被屏蔽的话)
delivery 结构存储了关于这些信号的处理方法
block 中如果对应的 1 号信号为 1,那么说明接下来进程如果收到 1 号信号,那么会将 pending 中关于 1 号信号对应的标志位设为 1,表示 未决,暂时不处理

在这里插入图片描述

其中,delivery存储了某个信号对应的处理方法,⭐「处理方法」包括三种:默认,忽略(不处理),用户自定义。并且 Linux 为默认和忽略提供了宏:默认 —— SIG_DFL忽略 —— SIG_IGN,而每个信号都有各自默认的处理方法

1.3 接口

1.3.1 sigset_t

首先认识一个数据结构 sigset_t,这个数据结构可以用来表示一个信号集,可以表示某个信号的状态。

  • 可以理解成一个位图,比方说,1 号信号在里面的比特位为1,那么表示有效;反之,0 表示无效,或者说没有这个信号

并且这个结构可以用来表示 blockpending,意义也是一样的,比如 sigset_t pendings,如果 1 号信号在里面的标志位为 1,那么表示 1 号信号在这个进程中的状态是未决的

1.3.2 信号集操作接口

1. sigemptyset(sigset_t* set) 					清空信号集,全部置0就对了
2. sigfillset(sigset_t* set) 					将信号集全置 1
3. sigaddset(sigset_t* set, int signo)  		将某个信号在这个信号集中标记为 有效
4. sigdelset(sigset_t* set, int signo) 			将某个信号在这个信号集中标记为 无效
5. sigismember(const sigset_t set, int signo) 	这个信号在信号集中是否 有效

这里面就是各种对 sigset_t 的操作了,后面举例子

1.3.3 signal

在这里插入图片描述上面不是说信号的处理方法有三种吗,而自定义处理方法就可以通过这个函数来指定

  • signum 表示要处理的信号,handler表示函数指针,就是自己定的函数了

(sigaction接口也可以修改信号对应的处理方案,signal 相对于它来说是简化版的)

举个例子:在进程中设置对 2 号信号的捕捉,捕捉之后打印一段话。之后对这个进程发送 2 号信号,这时候就会执行我们绑定的自定义函数了

在这里插入图片描述

1.3.4 sigprocmask

在这里插入图片描述作用:修改进程的阻塞信号集(block

how 参数常见的可以有 3 个值,假设当前进程的 信号屏蔽集为 block

  • SIG_BLOCK:往阻塞信号集中添加set中有效的信号,相当于让当前进程的 block | set
  • SIG_UNBLCOK:往阻塞信号集中去掉 set 中有效的信号,相当于让当前进程的 block | ~set
  • SIG_SETMARK,让当前进程的 block = set

oset 是输出型参数,如果不为空,那么会返回变化之前的 block ,便于后续恢复;如果不关心之前的状态,设为 NULL 就好了

举个例子
在这里插入图片描述屏蔽之后 2 号信号怎么处理?当然可以在程序中定期扫描没有处理的信号,也可以将 2 号信号的屏蔽字恢复为 0,比如:在后面将程序对 2 号信号的屏蔽取消之后,这个进程就会被终止了

在这里插入图片描述
可以看出虽然 pending2 号信号有效,但是由于屏蔽字,2 号信号的处理被拖延了。但是我们一旦取消屏蔽,而pending2号依然有效,2 号信号的处理函数就会被执行

1.3.5 sigpending

在这里插入图片描述
这个很简单了

  • set:输出型参数,会得到进程的 pending 集合,返回 0 表示一切顺利

2. 信号的处理

当进程收到信号之后,pending 中对应的标志位会被置为 1,然后⭐进程每次陷入内核态,再从内核态切换回用户态之前,内核大多会检查进程的信号状态,以处理这些未处理的信号,处理完后,对应标志位置为 0

先了解一下内核态和用户态

2.1 内核态和用户态

还记得虚拟地址空间吗,在 32 位下,虚拟地址空间中有 1G 内核空间,但是这部分空间不使用普通的页表,这 1G内核空间有自己独有的页表 —— 内核级页表,不同于用户空间的页表中 —— 每个进程都有一个自己的用户页表,而内核级页表所有进程共享,操作系统自己的数据和代码就是通过内核页表映射到物理内存上的

操作系统的代码数据必然不允许被随便访问,所以内核态页表带有权限验证。

  • 而进程的内核态和用户态其实就相当于两个身份,如果进程是内核态,那么也就可以访问内核的页表,也就可以访问所有内核代码数据,用户级的代码和数据当然也可以访问。内核态是特权模式,可以访问操作系统的数据和代码,也可以访问硬件设备,执行速度较快。

在这里插入图片描述

当进程需要从用户态切换成内核态的时候,会修改处理器的特权等级,从 3(用户态)改成 0(内核态),这里的处理器包括(CR0,CR3,CR4寄存器),当从用户态转化成内核态的时候,会保存用户态的上下文信息,并加载内核态的上下文信息,然后就可以访问内核态的页表,执行操作系统的内置代码,比如进程调度,异常处理等操作,当工作完成后,就会拿着计算结果,恢复用户态的上下文数据,再返回给用户,然后回到刚刚中断的代码后继续执行

总之,在程序的运行过程中,操作系统无形中会大量地访问系统硬软件资源,在这些访问过程中,操作系统都会切换成内核态,使用内核页表,然后调用内核部分的代码,最终再拿着计算的结果切换成用户态返回给用户

2.2 信号的监测和处理

所以当一个进程收到操作系统发送的信号之后,首先做的就是将 pending 中将对应的信号有效位置为 1,而该信号的处理一般是等到进程下一次嵌入内核态,再从内核态切换回用户态之前,因为在这之前,操作系统大都会检查该进程的信号状态。

  • 假设当前有个进程收到了信号 2,那么pending 上的相应位置也会被置为 1
  • 然后该进程突然执行了 write 等系统调用,就需要切换成内核态来执行操作系统的代码,以及访问硬件资源。然后按理来说,执行完 write 的时候,就应该拿着执行结果切回用户态返回给程序了
  • 但是在这之前,操作系统会以内核态的身份检查该进程的 pendingblock,如果 block中某信号标志位为 1,那么说明被屏蔽了,不用管它,而如果 block = 0, pending = 1 ,说明这个信号现在需要被处理
  • 如果信号的处理方法是 SIG_IGN,那么就忽略,将结果返回给用户,并从中断处继续往下执行
  • 如果信号的处理方法是 SIG_DEL,那么操作系统还是在内核态执行处理方法,比如终止进程…
  • 如果该信号的处理方法是用户自定义的函数,那么要执行这个函数,就又需要切换成用户态来执行这个处理函数(如果代码是恶意代码,那么以内核态的身份执行就存在风险)
  • 处理完这个函数之后,也不能直接将结果从用户层返回,因为还需要继续回到内核态,执行内核代码,比如更新进程的状态数据,在内核态中执行信号处理程序的收尾工作等
  • 最后再拿着执行结果返回给用户,从系统调用 write 处继续往后执行
  • 就完成了一次信号的处理

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

地震勘探基础(十一)之水平叠加处理

水平叠加处理 地震资料经过预处理,静校正,反褶积,速度分析和动校正处理后就要进行水平叠加处理。地震水平叠加处理是地震常规处理的重要环节。 假设一个共中心点道集有三个地震道,经过速度分析和动校正以后,水平叠加…

【数据结构】何为数据结构。

🚩 WRITE IN FRONT 🚩 🔎 介绍:"謓泽"正在路上朝着"攻城狮"方向"前进四" 🔎🏅 荣誉:2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2022博客之星T…

Tik Tok的海外娱乐公会(中亚、巴西、美国、台湾)怎么申请?

TIKTOK 公会海外市场潜力巨大 自 2016 年始,多家直播平台陆续拓展至东南亚、中东、俄罗斯、日韩、 欧美、拉美等地区 海外市场作为直播发展新蓝海,2021 年直播行业整体规模达百亿美元, 并维持高速增长 TikTok 直播市场空间 TikTok 已经成…

【 Python 全栈开发 - WEB开发篇 - 31 】where条件查询

文章目录 一、where条件查询1.关系运算符查询2.IN关键字查询3.BETWEEN AND关键字查询4.空值查询5.AND关键字查询6.OR关键字查询7.LIKE关键字查询普通字符串含有%通配的字符串含有_通配的字符串 一、where条件查询 MySQL 的 where 条件查询是指在查询数据时,通过 wh…

网络安全系统教程+渗透测试+学习路线(自学笔记)

一、什么是网络安全 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域,都有攻与防两面…

Qt6 C++基础入门3 对话框与MainWindow

目录 对话框MainWindow菜单工具栏 对话框 目前的对话框主要有以下几大类 文件对话框( QFile Dialog)消息对话框( QMessageBox)输入对话框( QInputDialog)颜色对话框( QColorDialog)字体对话框( QFontDialog) 这是七大对话框及其基本用法的实例参考,所有代码都写在…

四、LLC 谐振变换器

变换器实现 ZVS 的限制 全面了解LLC谐振变换器实现ZVS的条件,把变换器主电路变形成图所示形式。其中 Coss1、Coss2分别为开关管 S1、S2 漏-源极间的寄生电容,并且Coss1Coss2 Coss 。Cstray为与谐振网络并联的等效寄生电容,则变换器在 ZVS 条…

万维网服务器

一、域名解析gethostbyname函数 struct hostent {char *h_name; /* 官方域名 */char **h_aliases; /* 别名*/int h_addrtype; /* 地址族(地址类型) */int h_length; /* 地址长度 */char **h_addr_list; …

QT+OpenGL高级光照 Blinn-Phong和Gamma校正

QTOpenGL高级光照1 本篇完整工程见gitee:QtOpenGL 对应点的tag,由turbolove提供技术支持,您可以关注博主或者私信博主 Blinn-Phong 冯氏光照:视线与反射方向之间的夹角不小于90度,镜面光分量会变成0.0(不是很合理&am…

宝塔面板搭建thinkphp后请求中去除index.php后缀

宝塔面板搭建thinkphp后请求中去除index.php后缀 nginx配置 在宝塔面板网站中绑定thinkphp的public,添加站点 点击站点设置按钮打开项目设置页面 找到配置文件 选项,然后在 22行 后添加一下代码 location / {if (!-f $request_filename) {rewrite …

机器学习算法分类(三)

在机器学习中,又分为监督学习、无监督学习、半监督学习、强化学习和深度学习。 监督、无监督、半监督学习 机器学习根据数据集是否有标签,又分为监督学习、无监督学习、半监督学习。 监督学习:训练数据集全部都有标签无监督学习&#xff1a…

javaScript蓝桥杯---传送门

目录 一、介绍二、准备三、目标四、代码五、知识点六、完成 一、介绍 日常浏览网页的时候,我们会发现一个问题,当页面太长、内容太多的时候我们很难快速浏览到心仪的内容。为了解决这个烦恼,优秀的产品研发团队发明了一种类似传送门的功能&a…

深度学习的各种卷积的总结

如果你听说过深度学习中不同种类的卷积(比如 2D / 3D / 1x1 /转置/扩张(Atrous)/空间可分/深度可分/平展/分组/混洗分组卷积),并且搞不清楚它们究竟是什么意思,那么这篇文章就是为你写的,能帮你…

STM32单片机GPS北斗无线防丢定位超出距离报警系统NRF24L01

实践制作DIY- GC0136-GPS北斗无线防丢定位超出距离报警系统 基于STM32单片机设计-GPS北斗无线防丢定位超出距离报警系统 二、功能介绍: 主机:STM32F103CxT6系列最小系统板OLED显示器NRF24L01无线通讯模块GPS北斗双模定位模块蜂鸣器距离加减2个按键1个模…

BurpSuite2023测试越权漏洞

BurpSuite2023测试越权漏洞 BurpSuite安装创建项目 - 打开内置浏览器越权漏洞测试问题处理 BurpSuite安装 官网下载社区版并安装,下载地址:链接: https://portswigger.net/burp 安装成功后图标 创建项目 - 打开内置浏览器 打开BurpSuite&#xff0c…

为何要将行驶证转为Excel?在线怎么操作?需要注意些什么?

一、为何要将行驶证转为excel表格?有何好处? 将行驶证转为Excel一般是为了方便信息的整理和管理。将行驶证上的信息录入Excel表格中,可以实现快速搜索、排序和筛选等功能,避免了手动整理信息的繁琐和容易出错的问题。此外&#xf…

Lecture 17 Machine Translation

目录 Statistical MTNeural MTAttention MechanismEvaluationConclusion Machine translation (MT) is the task of translating text from one source language to another target language why? Removes language barrierMakes information in any languages accessible t…

chatgpt赋能python:Python如何从右往左取数

Python如何从右往左取数 在Python编程中,有时候需要从右往左获取列表、字符串等数据结构的元素,而不是从左往右。这样做的好处在于可以更快地访问最后几个元素,或者进行一些反向操作。本文将介绍Python中从右往左取数的方法。 索引与切片 …

JDBC Utils 详解(通俗易懂)

目录 一、前言 二、JDBCUtils说明 1.背景及起因 : 2.示意图 : 3.JDBCUtils类的定义 三、JDBCUtils应用 1.DML的应用 : 2.DQL的应用 : 四、总结 一、前言 第三节内容,up主要和大家分享一下JDBC Utils方面的内容。注意事项——①代码中的注释也很重要&#x…

性能测试loadrunner

目录 基本概念 性能工具jemeter代码调试 loadrunner实战代码笔记 使用Loadrunner的步骤 性能指标分析结果 基本概念 一、什么是性能: 性能:是用来描述产品除功能外的所具有的速度,效率和能力的综合能力评价。 二、什么是性能测试&…