Linux小黑板(10):信号

news2024/11/18 23:35:48

我们写在linux系统环境下写一个程序,唔,"它的功能是每隔1s向屏幕打印'hello world'。"

这时,我们在键盘上按出"Ctrl + C"后,进程会发生什么??

我们清晰地看到,进程已经在我们按出"Ctrl + C"后,进程退出了。那为什么会出现这个现象呢??是什么引发了当前运行的前台进程退出呢?

那么我们也就不卖关子了,"Ctrl +C"是一个组合键,作用就是向当前进程发送2号信号。

那么什么是信号呢?信号是如何产生的呢?进程收到信号后的处理动作又是什么呢?

-----前言


一、认识信号

我们在日常生活中,时常都会与信号打交道。例如,在学校听到铃声,在公路上看到红绿灯,但是如果我们从没有上过学,或者从没有去过公路,我们压根不知道出现眼前这种情况,我们的对应动作是什么。因此,我们对信号的认识在于,"识别信号,行为产生",不仅仅是在于能够看到,能够知道这种情况下,是给我是遇到信号了,并且我还需要知道学校铃声响起,我就该上课或者下课了,红灯亮起,此时就不应该在将脚迈上公路。

为什么进程需要信号呢?

我们从识别信号到行为产生,首先就需要有人告诉你这是什么信号,面对这样的信号你要做出的行为是什么?"这是红绿灯","绿灯行红灯停"。唔,这很符合当下,是你通过学习交通知识得出的,并且你会将其信号翻译成形如上述的形式(如果你仍持有人类该有的理性)。这总比让一位主持交通管理的执行员扯着嗓门、比划着让哪路上的行车停止,哪路上的行车启动的行为要方便很多……

当你使用"Ctrl + C"组合热键时,你如何知道该进程收到了什么样的信号呢?你说,是2号信号(你前文说过)。那如果是"Ctlr+Z"组合键呢?恐怕,你只会抓耳挠腮地喃喃信号此时并非很吃香,因为你并不认识该信号,也就更不会有行为的产生。由此,识别信号其实是有成本的。

进程识别信号的本质,与我们识别信号的行为是一致的—— "识别信号,行为产生"。

Linux中信号宏定义:

/usr/include/bits/signum.h

Linux中的信号集:

kill -l 查看
[1,31]:普通信号
[34,64]:实时信号


二、信号产生

(1)信号产生的方式

键盘发送:

在了解了什么是信号后,我们现如今把目光聚焦到信号是如何产生的问题上来。例如,前文常提的两个组合键 "Ctlr +C" , "Ctrl + Z",Linux命令行就会从键盘上获取这两个组合键,并把它们解释为信号,发送给当前进程。

硬件异常:

我们举例一个除0操作的错误代码,并且用核心转储查看。

core-file + 形成的核心转储的文件

我们知道,该进程执行除0操作时收到了信号8。

如何理解除0错误?

如何理解未初始化指针解引用?

我们对一个未完成赋值指针进行解引用。

软件条件:

系统库中提供一个alarm函数,意为"闹铃"。即,过段时间就会给该进发送14闹铃信号。

程序运行3s后,进程收到alarm信号后退出。

当然软件条件还有管道,例如读端已经关闭,写端一直在写,OS绝不会允许这样浪费资源,因此会向正在运行的写端发送管道信号(SIGPIPE)。

系统调用:

#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);

当然,我们仍然可以通过系统调用向该进发送信号。这个kill函数你是否见着它很熟悉??这不就是我们在命令行输入的kill + signum + pid嘛? 是的! 命令行解释器的底层就是去调用的这个函数!


三、信号保存与阻塞

前文讲述了信号是如何发送的,信号是如何产生的条件。但事实上,信号产生后,只有接收方接收到了,才能进行之后的"递达",也就是行为产生。因此,当OS向进程发送信号时,该进程怎么知道OS向它发送了信号?OS发送了什么信号呢?

又比如,现在你叫张三,你很不喜欢讲台上的老师,于是乎,你根本不在乎他说什么。那么他"发出的任何信号",都不会被你识别,更别说"递达",即行为产生。由此,如果进程选择不接收OS发送的信号,又该作何处理??

信号相关概念:
1.实际执行信号的动作称为:信号抵达。
2.信号从产生到递达之间的状态:信号未决。
3.进程可以选择阻塞某个信号。
4.被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。

注意:
阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作

信号在内核中的表示:

block: 表示阻塞信号集
pending: 表示接收信号集
handler: 信号集方法

正如前文所述,linux内核中,信号num是一堆宏定义整数。

block、pending集是被设计成一种位图的数据结构!举个unsigend_int的例子,32个比特位表示信号个数可以是[1,32]。0表示阻塞(未接收)信号,1表示未阻塞(接收)信号。每一个pending集的比特位,都与handlers这个数组下标的位置一一对应。handlers数组是一个函数指针数组,里面存放的是每一种信号接收时,行为产生函数的地址。

所以,如果你想要改变一个信号,对应的默认行为,你就只需要将你实现的handlers方法函数的地址,填入到内核数据结构中handlers数组里即可。

四、信号处理

根据前文认识了什么是信号,以及信号的产生,我们可以得出如下的结论:
信号是发给进程的,信号产生于操作系统。

可是,我现在的问题是,当前进程收到信号后,就必须要放下"手头"的事,立马去处理到来的信号嘛?毕竟,当我妈叫现在我吃饭,这是一个信号,但是我现在正在写博客、正在上网课,我可以选择继续写我的博客,继续上我的课,当然我也可以选择立即直接扔掉手中敲打的键盘,也可以立即将那喋喋不休的腾讯会议结束掉,立刻前去吃饭。

由此,我们对于信号的处理似乎有,唔大概三种处理方式:

默认行为、忽视行为、自定义行为。

但是,我妈叫我吃饭了,我们是选择了继续干完当前的事,但是干完这些事之后,我才会去吃饭。因此,接收信号后,并不代表一定要产生行为,可以将它先保存,并在适合的时候进行处理

那么什么算是合适的适合呢??

这里也不卖关子,内核态返回用户态的时候(这个之后会细谈)!

五、内核态vs用户态

我们知道了信号是发送给进程的,发送方是OS。但是OS是如何发送信号的?我们接收到信号时,该进程是怎么知道的?一定需要到进程的内核数据结构中去,但是我们能去吗?肯定不行!这个行为,只有OS才能帮我们这样做。同样,如果我们需要自定义信号捕捉(信号递达),不是我们去更改那个handler表,因为我们并没有权限!OS不信任任何人!

(1)身份切换

(2)内核地址空间

我们使用库函数时,只区分动态库和静态库。动态库的函数地址会在程序运行时加载进共享区,而使用静态库函数时,函数地址会被编译进源程序中,存储在代码区。

那么我们使用系统调用接口,我们是怎么找到它们的地址并,调用它们的?

总结:

信号产生:

信号抵达:

本篇到此结束,感谢你的阅读。

祝你好运,向阳而生~

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

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

相关文章

UML2——行为图

目录 一、前言 二、活动图 三、交互图 3.1 一般序列图 3.2 时间约束序列图 3.3 协作图 四、用例图 五、状态图 一、前言 UML 是由视图&#xff08;View&#xff09;、图&#xff08;Diagrams&#xff09;、模型元素&#xff08;Model elements&#xff09;和通用机制等几…

(图像分割)基于图论的归一化分割

解释&#xff1a;将图像映射成图&#xff0c;以图为研究对象&#xff0c;利用图的理论知识获得图像的分割。 下面介绍&#xff1a;图的基本理论&#xff0c;基于图论的归一化分割算法 一、图的基本理论 图G&#xff1d;&#xff08;V&#xff0c;E&#xff0c;&#xff09;&…

《管理世界》数据复现:国有资本参股如何影响民营企业?——基于债务融资视角的研究

摘要&#xff1a; 本文以债务融资为切入点&#xff0c;从“未阐明的规则”和“阐明的规则”两个层面探讨了国有资本参股的“反向混改”是否以及如何影响民营企业。研究发现&#xff1a;国有资本参股可以显著降低民营企业的债务融资成本&#xff0c;扩大债务融资规模。…

性能测试——LoadRunner: Controller的使用

Controller Controller是用来创建测试环境&#xff0c;执行在VUG中编写的测试脚本 可以直接点击Controller的快捷方式打开,也可以在VUG中打开 这里将虚拟用户数设置为3,比较适合自己的电脑性能 整个controller分为下面几个模块 这里先设置左下角的目标计划 设置初始化:双击…

PHP 8.1.14升级低版本openssl扩展的操作方法

问题背景&#xff1a; PHP8.1.4内嵌openssl源码编译出来的openssl库版本号是1.0.2.x系列&#xff0c;低版本的openssl扩展存在安全漏洞&#xff0c;需要将该扩展升级openssl 社区最新版本3.0.8 操作步骤&#xff1a; 安装最新版本的openssl wget https://github.com/openssl…

Java面试总结(四)

synchroize的实例、静态、代码块的锁对象 修饰实例方法 修饰静态方法 修饰代码块 1、修饰实例方法 &#xff08;锁当前对象实例&#xff09; 给当前对象实例加锁&#xff0c;进入同步代码前要获得 当前对象实例的锁 。 synchronized void method() {//业务代码 }2、修饰静…

在vue中如果computed属性是一个异步操作怎么办?

在计算属性中使用异步方法时&#xff0c;可以使用async/await来处理异步操作。由于计算属性是基于它们的依赖缓存的&#xff0c;所以我们需要使用一个返回Promise的异步方法来确保计算属性能够正常运行。 下面是一个简单的示例&#xff0c;演示如何在计算属性中使用异步方法&am…

P6入门:P6 Professional常用快捷键/热键

目录 一 引言 Primavera P6 专业版 Primavera P6 EPPM&#xff08;网络客户端&#xff09; Primavera P6 Alt 键 Primavera P6 功能键 一 引言 在 Oracle Primavera P6 中&#xff0c;有热键命令可以节省宝贵的时间。尤其是作为一个与 Primavera P6 长打交道人熟练掌握这…

苹果手机备份的文件在电脑什么地方 苹果备份文件怎么查看

在这个网络信息时代&#xff0c;为手机进行定期备份已经成为了家常便饭。在使用备份软件对苹果手机进行备份后&#xff0c;苹果手机备份的文件在什么地方&#xff0c;苹果备份文件怎么查看呢&#xff1f;本文就带大家来了解一下。 一、苹果手机备份的文件在电脑什么地方 大家…

数据库三大范式、BC范式、第四范式

目录第一范式&#xff08;1NF&#xff09;&#xff1a;原子性&#xff08;存储的数据应该具有“不可再分性”&#xff09;第二范式&#xff08;2NF&#xff09;&#xff1a;唯一性 (消除非主键部分依赖联合主键中的部分字段)&#xff08;一定要在第一范式已经满足的情况下&…

Python之flask基础

文章目录入门小案例及认识路由小总结配置文件路由系统路由支持正则cbv &#xff08;用的比较少&#xff09;模板渲染变量及循环请求响应pipreqs&#xff08;找当前项目依赖的包&#xff09;闪现&#xff08;flash&#xff09;请求扩展&#xff08;类似中间件&#xff09;猴子补…

【Redis】Redis集群之哨兵机制

【Redis】Redis集群之哨兵机制 文章目录【Redis】Redis集群之哨兵机制1. 哨兵的作用和原理1.1 哨兵的作用1.2 redis服务状态监控1.3 选举新master1.4 故障转移1.5 总结2. 搭建哨兵集群2.1 准备实例和配置2.2 启动2.3 测试3. RedisTemplate的哨兵模式1. 哨兵的作用和原理 1.1 哨…

1634_linux中把pdf拆分成独立的图片文件

全部学习汇总&#xff1a; GreyZhang/toolbox: 常用的工具使用查询&#xff0c;非教程&#xff0c;仅作为自我参考&#xff01; (github.com) 最近工作学习之中使用pdf的频次非常高&#xff0c;这种格式的通用性的确是不错。在目前的很多平台上都有很好用的软件。不过&#xff…

ios设备管理软件 2.16.9官网Mac/Windows下载电脑版功能介绍

imazing 2.16.9官网Mac/Windows下载电脑版是款针对苹果设备所打造的管理工具。iMazing为用户提供多种设备管理功能&#xff0c;每一位用户都能以自己的形式管理苹果设备。iMazing与苹果设备连接后&#xff0c;用户就可以轻松传输文件&#xff0c;浏览保存信息等。 应用介绍 i…

Zookeeper3.5.7版本——集群启动停止脚本

目录一、Zookeeper3.5.7集群部署&#xff08;linux环境-centos7&#xff09;二、3台服务器信息三、Zookeeper3.5.7集群启动停止脚本3.1、编写zk.sh脚本3.2、增加脚本执行权限3.3、执行Zookeeper 集群的zk.sh脚本四、执行脚本启动Zookeeper 集群五、执行脚本查看Zookeeper 集群状…

Lesson11---分类问题

11.1 逻辑回归 11.1.1 广义线性回归 课程回顾 线性回归&#xff1a;将自变量和因变量之间的关系&#xff0c;用线性模型来表示&#xff1b;根据已知的样本数据&#xff0c;对未来的、或者未知的数据进行估计 11.1.2 逻辑回归 11.1.2.1 分类问题 分类问题&#xff1a;垃圾…

SS-ELM-AE与S2-BLS相关论文阅读记录

Broad learning system for semi-supervised learning 摘要&#xff1a;本文认为&#xff0c;原始BLS采用的稀疏自编码器来生成特征节点是一种无监督学习方法&#xff0c;这意味着忽略了标注数据的一些信息&#xff0c;并且难以保证同类样本之间的相似性和相邻性&#xff0c;同…

CentOS 7.9汇编语言版Hello World

先下载、编译nasm汇编器。NASM汇编器官网如下图所示&#xff1a; 可以点图中的List进入历史版本下载网址&#xff1a; 我这里下载的是nasm-2.15.05.tar.bz2 在CentOS 7中&#xff0c;使用 wget http://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2下载…

用Python Flask为女朋友做一个简单的网站(附可运行的源码)

&#x1f31f;所属专栏&#xff1a;献给榕榕&#x1f414;作者简介&#xff1a;rchjr——五带信管菜只因一枚&#x1f62e;前言&#xff1a;该专栏系为女友准备的&#xff0c;里面会不定时发一些讨好她的技术作品&#xff0c;感兴趣的小伙伴可以关注一下~&#x1f449;文章简介…

微信小程序原生开发功能合集四:复选框组件的封装

本章实现小程序复选框组件的封装,使用check及check-group组件实现复选框,封装数据加载过程,并自动实现数据解析及生成,实现相应方法。   另外还提供小程序开发基础知识讲解课程,包括小程序开发基础知识、组件封装、常用接口组件使用及常用功能实现等内容,具体如下:  …