linux信号| 学习信号三步走 | 学习信号需要打通哪些知识脉络?

news2024/12/24 3:19:39

        前言: 本节内容主要讲解linux下信号的预备知识以及信号的概念, 信号部分我们将会分为几个阶段进行讲解:信号的概念, 信号的产生, 信号的保存。本节主要讲解信号

        ps:本节内容适合学习了进程相关概念的友友们进行观看哦

目录

什么是信号

常见的信号有哪些

进程如何认识信号

前台启动与后台启动

信号的种类

信号的处理方式

键盘数据如何变成信号

针脚

中断向量表


什么是信号

         在我们生活当中, 有许多都是信号的模式。 ——比如我今天点了一个外卖, 我点了之后就在宿舍打游戏了。 之后, 外卖小哥到了, 给我打了一个电话, 敲我的门。 那么这种情况, 就叫做信号产生当我收到这个信号的时候, 我可能有事情, 那么我即便收到了信号, 也不会立即处理, 而是把事情忙完之后, 再进行处理。 也就意味着, 信号暂时得被我记录下来。 ——我们取外卖的动作, 就叫做信号处理; 外卖小哥给我们打电话叫做信号的产生; 而我们可能在做更重要的事情, 比如打游戏, 我们得等一等, 所以我们会把信号产生的这个事情记录下来, 在合适的时候进行处理, 这个就叫做信号保存 整个流程下来, 就叫做信号产生到信号处理的生命周期!

常见的信号有哪些

        我们的上课铃声, 我们的门铃, 取快递,爸爸妈妈都脸色不太好, 古代的冲锋号, 狼烟等等都叫做信号。 

进程如何认识信号

        虽然计算机内部有信号, 但是我们的进程是怎么认识信号的呢?

  •         对于进程来说, 进程一定能够识别并处理信号的能力
  •         并且, 进程即便没有收到信号, 也能知道那些信号该怎么处理。——这个信号处理能力是必须是属于进程内置功能的一部分。
  •         当进程真的收到了一个具体的信号的时候, 进程可能并不会立即处理信号, 因为进程可能在做更重要的事。 
  •         进程当信号产生, 到信号被处理, 这个中间一定有着时间窗口, 所以进程必须有临时保存信号的能力。

        所以, 综上, 我们就知道, 什么叫做认识信号?——认识信号就是能够先识别信号, 然后知道信号的处理方法。 就比如我们人, 我们知道了红灯, 门铃这些信号该干什么, 是因为我们记住了这些信号的识别方法和处理方法。

前台启动与后台启动

我们运行下面这个程序

#include<iostream>
using namespace std;
#include<unistd.h>


int main()
{
  while (true)
  {
    cout << "i am a crazy process" << endl;
  }                                                                                                                                                                                  return 0;
}

然后运行结果如下:

        我们除了进程再运行, 其他看不出什么问题。 但是呢, 上面的进程一直在跑, 我们按什么都没有用, 所以这个时候我们ctrl + c, 就可以让进程退出。 

        为了更好的测试我们这里让程序睡眠上一秒钟:

#include<iostream>
using namespace std;
#include<unistd.h>


int main()
{
  while (true)
  {
    cout << "i am a crazy process" << endl;
    sleep(1);
  }                                                                                                                                                                                  return 0;
}

这个程序运行起来了, 但是问题是我们再输入什么都没有用了。 这是为什么?这是因为我们启动的进程是一个前台进程什么是前台进程, 这种我们的进程启动后, 我们的bash进程就不再接收任何指令了, 这种进程, 就叫做前台进程。 

现在, 我们在进程运行的时候输入一个&, 这个的意思是后台进程。

        因为进程的作用就是打印数据, 所以他还会在命令行上打印数据, 并且我们可以在命令行上输入指令, bash会接收这些指令。

        但是问题是我们使用ctrl + c杀不掉这个进程了, 如下图:

这是因为在Linux终端中, 一次登录中, 一个终端, 一般会配上一个bash。 每一个登录, 只允许一个进程是前台进程, 可以允许多个后台进程。 像这种后台进程只能使用kill -9 PID杀掉这个进程。 

        现在我们要说的是, 为什么我们运行一个myprocess后, 再输入ls等指令就没用了呢?——这是因为我们./myprocess默认是前台进程启动。 而我们说过, 每一个登录, 其实只允许一个进程是前台进程。 要知道, 我们的bash也是进程, 而且也是前台进程!那么, 当我们的./myprocess后, 我们的./myprocess就变成了前台进程, 而bash变成了后台进程, 那么再在bash里面输入就没有作用了。 所以, 前台和后台的本质区别就是——谁来获取键盘输入!当我们运行myprocess之后, 获取键盘输入的就是我们的myprocess了, 所以再输入指令没有反应, 因为myprocess不会对指令做出反应!因为bash收不到指令

        再回过头来看我们的这个问题——为什么我们myprocess &, 让进程后台运行之后ctrl + c后杀不掉这个./myprocess进程呢? ——这是因为当我们的后台运行myprocess接收ctrl + c的进程是我们的bash进程, myprocess接收不到命令, 也就不能杀掉这个进程。 

        那么问题又来了, 我们的bash进程ctrl + c后, 为什么不会被干掉呢? 这是因为我们的bash进程内部对于ctrl +c做了特殊的处理。 

        那么, 当我们myprocess后台运行的时候, 随让我们同样可以看到打印, 但是请问这个时候我们可以继续输入指令吗? 

        答案是可以的, 就像上图, 当我们后台运行myprocess进程, 这个时候虽然会继续向显示器上面打印数据, 但是当我们输入指令, 即便这个指令会被数据断开, 但是bash命令会忽略这些后台打印的数据。 

         也就是说, 表面上看我们的指令是被扰乱的, 但是其实这些指令并没有被扰乱, 这个指令还是完整的输给了前台进程。 我们为什么看到的是乱的仅仅是因为我们在进行输入的时候, 字符在显示器上面被回显出来了, 我们在输出上面互相干扰了。 ——我们输入有输入缓冲区, 输出有输出缓冲区输入缓冲区也就是bash的输入缓冲区, 我们使用ls命令, 本质上是ls输入到bash的输入缓冲区当中。 并且, 不光光是给输入缓冲区了, 同时也给了输出缓冲区显示器上面给我们回显了。 

       每当我们登录上一个终端, 每一个终端都会配上一个bash。 一般情况下,bash是前台进程, 他会获取终端的键盘输入, 但是当我们执行一个进程的时候, 它默认会变成一个前台进程, bash会变成一个后台。 整个的在我们的进程一次登录当中, 只允许一个进程是前台, 多个进程是后台。 

        而之所以我们的ctrl + c能够杀掉前台进程, 是为什么——ctrl + c是我们的键盘输入, 是被前台进程收到的。 ——所以在进程ctrl + c的时候, 本质是被前台进程解释成为收到了信号,这个信号是2号信号。 

信号的种类

        kill -l可以查看我们当前的linux系统一共支持多少信号。 ——注意, 没有0号信号, 没有32, 33好信号。 一共62个信号。 其中, 1 ~31被称为普通信号,后面的信号被称为实时信号。 什么是实时信号——我们说过, 一个信号产生了, 那么我们可以不去立即处理, 这种叫做普通信号, 而一旦信号产生了, 我们必须尽快处理, 这种信号被称为实时信号。  

        我们的ctrl + c 其实就是出发了二号信号——SIGINT.

信号的处理方式

        当我们收到一个信号的时候, 我们会在合适的时候处理这个信号。 信号的处理方式是什么——

  •         就比如当我们路过红路灯的时候, 遇到绿灯, 我们会走, 红灯我们会停下来——这就是我们处理信号的默认动作;
  •         有一些人看到红灯之后不管红灯, 直接闯红灯——这就叫忽略;
  •         红灯亮的时候, 有些人天生就是显现包, 红灯一亮, 他就唱歌, 他就跳舞等等, 这些动作是他们自己按照自己的想法来的——这就叫做自定义动作。 这种自定义动作通常叫做信号的捕捉。 

        我们上面说的收到二号信号的默认动作, 就是终止自己。 

如何捕捉信号呢?就是使用下面的函数:

        这里的signal函数, 谁要调用它, 就要传送两个参数, 第一个参数就是上面的signal标号。 而后面的hander就是谁调用这个函数, 执行这个信号的自定义捕捉动作!!! 未来如果我们想收到一个信号, 并在收到这个信号时, 让他自定义去执行动作, 就把要执行的动作和信号通过这个函数进行绑定!——即这个函数, 是用来修改特性进程对信号的处理工作的。 

        第一个参数是int类型, 传送的是信号的编号。 确定的是哪一个信号。 所以, 我们就要传送这个信号的编号。 下面是宏定义:

        然后, 定义下面的代码,并执行:

        然后我们就会发现, 原本的ctrl + c会直接退出, 但是现在不退出了, 而是执行我们的自定义的动作。 那么我们就验证了, 我们的ctrl + c其实就是要发送信号。 并且默认动作和自定义动作只会执行一个。 

        注:想要让它退出, 就是要使用exit调用。 

        还有一个问题就是为什么我们使用signal的时候, 要把它放在一开始, 而不是放在后面或者中间位置呢? 

        这是因为signal只需要设置一次, 往后进程的生命周期里面, 所有的都有效。那么问题是——我们的hander方法是我们的在调用signal函数的时候就调用的还是后面遇到信号的时候再调用的呢? 就比如我们和别人做约定, 我们需要遇到红灯就唱歌。那么我们是定下约定的时候就唱歌呢? 还是遇到红灯再唱歌呢?一定是我们遇到红灯时再唱歌, 那么是不是如果看不到红灯, 那么就永远不需要执行约定。——类似的, 也就是说, 我们后续没有收到这个信号 那么这个新创建的方法, 就永远也不需要调用

        注:有些信号可以被捕捉, 有些不可以被捕捉。 比如9号,19号信号。 

键盘数据如何变成信号

        根据冯诺依曼体系结构, 我们的进程是不能直接访问硬件, 也就是键盘的。 它必须由它的管理者直接访问, 所以我们键盘的按下, 肯定是由操作系统第一个知道的。 ——操作系统是如何知道键盘被按下, 并且把键盘里面的数据输入到自己里面的呢? 也可以换一个说法就是操作系统是怎么知道键盘上有数据了的呢?现在看下面一张图:

        想要知道键盘有数据, 最好的方法就是操作系统定期去检查这个键盘。 因为linux下一切皆文件, 所以键盘也是文件键盘也有自己的文件描述符有自己的内核缓冲区键盘读取的本质, 就是把键盘硬件的数据拷贝到键盘文件的缓冲区里面。 

        可是计算机中的外设太多, 操作系统怎么知道我们应该向哪个外设中拿到什么数据呢?另外, 我们知道, 我们的cpu, 虽然是不和外设直接打交道的, 但是这是在数据层面。 在控制层面, 我们的cpu还是能读懂外设的。 如何读懂外设? 就是利用cpu周边的针脚, 利用一种叫做中断号的概念!    

针脚

  •         我们的cpu上面有很多很多的针脚, 这些针脚是集成在主板上面的, 而我们的键盘显示器内存, 各种设备也是插在主板上面的。 我们对应的键盘, 是直接能够和cpu连接到的。 我们虽然cpu不从键盘当中读取数据, 但是键盘能够从硬件层面上发送一个硬件中断。 
  •         也就是说, 操作系统在进行我们工作的时候, 就忙自己的, 但是一旦键盘上面有数据, 键盘就会通过硬件单元, 把我们的键盘当中的信息发送给cpu。
  •         那么我们要知道什么? 我们要知道的是, 从外设到内存, 再到cpu, 轮询的检查, 对于操作系统的负担是很大的。 所以操作系统不会去检查硬件里面是否有数据, 而是硬件有数据了, 通过硬件中断, 来给我们的cpu发送中断, 来让操作系统完成拷贝。 每一种中断, 都有一种中断号的概念。        
  •         这个中断号及类似于123456789这种数字, 假如我们的键盘的中断号是1, 未来他有数据, 就直接通过cpu连接的针脚, 向cpu内发送某个中断号, 然后针脚接收中断号的高低电频, 由cpu来解释这些电频, 确定中断号是几。 所以, 也就是说, 当键盘中有数据, cpu就能获取这个键盘的中断号, 他就记下来了。——这个过程更进一步理解就是:我们知道cpu里面有寄存器, 可以保存数据。 cpu中的寄存器凭什么可以保存数据? 本质上就是对我们的寄存器在充放电的过程,键盘给cpu发送高低电频,我们的针脚能够识别这些高低电频,  而cpu里面的寄存器里面有一个个硬件单元,这些高低电频给寄存器里面的硬件单元充放电。 并且这些电频有高有低, 到了软件层面,就被解释成为了一个个二进制。 

中断向量表

        在我们的软件层面上, 我们的操作系统内, 比较靠前的位置, 当操作系统开机的时候, 就会生成一张中断向量表。

        这个中断向量表里面是方法的地址, 主要是包括直接访问外设的方法, 主要是磁盘, 还有各种显示器, 键盘的设备。 这里面其实放着的就是函数指针, 所以他会指向操作系统当中的某个位置。 

        所以, 我们的外设, 一旦获取了数据, 就会通过中断单元, 将数据写到cpu的寄存器当中, cpu的寄存器就获得了一个中断号, cpu拿着中断号去操作系统的中断向量表当中寻找外设的方法。 然后执行这个方法, 而这个方法, 才是我们的数据从外设拷贝到内存中的方法。 操作系统在将数据从外设拿到内存的时候就会判断。 判断这个数据是数据还是控制, 如果是控制, 比如ctrl + c。呢么操作系统就会把ctrl + c转化为2号信号, 发送给进程。 进程进而直接终止。 

这里有一个概念, 叫做信号的产生和我们的代码的运行是异步的。 这是为什么? 
        就比如我们老师给我们上课, 如果老师这个时候口渴了, 想要喝水, 他就让学生A去买水。 这个时候老师就和全班同学说先上自习, 等张三回来再上课。 这个过程, 就叫做同步的。 但是第二天, 老师又口渴了, 老师又让学生A去买水, 但是这个老师这次开始不等张三了, 他就继续上课。 张三呢, 随时随地可能回来, 老师不管, 老师就做他自己的工作。 两人之间你做你的, 我做我的, 互不干扰, 这叫做异步。 ——也就是说, 我们今天再运行我们的代码的时候, 他什么时候产生我们并不知道。 他可能随时随地地产生, 但是我们不需要等待这个信号。 这就说信号和我们的代码的执行是异步的。 ——这就有了信号的概念——信号是进程之间时间异步通知的一种方式, 属于软中断!

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

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

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

相关文章

轻松重置 MySQL 8.0 Root 密码的简便方法!

在Windows环境下安装MySQL数据后&#xff0c;如果忘记了 MySQL 8.0 的 root 密码&#xff0c;不必担心&#xff01;通过 --skip-grant-tables 和 named-pipe 模式登录后&#xff0c;只需几步简单的 SQL 命令即可重置密码&#xff1a;刷新权限表、修改密码、再刷新权限&#xff…

SpringBoot+Thymeleaf租房管理系统

> 这是一个基于SpringBootThymeleafBootstrap实现的租房管理系统。 > 功能比较完善&#xff0c;包括用户注册/登录、房源登记、账单费用配置、统计报告等功能。 > 模拟真实使用环境&#xff0c;包括了自然人与法人的身份证明录入、房产证信息录入、通过邮件推送月…

E2VPT: An Effective and Efficient Approach for Visual Prompt Tuning

论文汇总 存在的问题 1.以前的提示微调方法那样只关注修改输入&#xff0c;而应该明确地研究在微调过程中改进自注意机制的潜力&#xff0c;并探索参数效率的极限。 2.探索参数效率的极值来减少可调参数的数量? 解决办法 提示嵌入进行transformer中 提示剪枝 Token-wise …

学生网上选课系统设计与实现

学生网上选课系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装学生网上选课系统软件来发挥其…

托盘检测系统源码分享

托盘检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

两数之和、三数之和、四数之和

目录 两数之和 题目链接 题目描述 思路分析 代码实现 三数之和 题目链接 题目描述 思路分析 代码实现 四数之和 题目链接 题目描述 思路分析 代码实现 两数之和 题目链接 LCR 179. 查找总价格为目标值的两个商品 - 力扣&#xff08;LeetCode&#xff09; 题目…

牛客周赛 Round 61 (C++实现)

比赛链接&#xff1a;牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com) 文章目录 1.致十年后的我们1.1 题目描述1.2 思路1.3 代码 2.简单图形问题2.1 题目描述2.2 思路2.3 代码 3. 小红的机器人构造3.1 题目描述3.2 思路3.2.1 问题13.2.2 问题23…

力扣 中等 1901.寻找峰值II

文章目录 题目介绍题解 题目介绍 题解 需要明白一个事实&#xff1a;从任意一个点出发&#xff0c;可以经过一个递增路径&#xff0c;找到一个极大值点。 求出一行的最大值&#xff0c;如果这行最大值比上面的要小&#xff0c;那峰值&#xff08;之一&#xff09;就会在上面 …

最具成长潜力奖!2024中国互联网发展创新与投资大赛(深圳)落幕,爱加密载誉而归!

近日&#xff0c;由中央网信办信息化发展局、广东省委网信办指导&#xff0c;中国互联网发展基金会、中国互联网投资基金、深圳市委网信办联合主办的2024中国互联网发展创新与投资大赛&#xff08;深圳&#xff09;正式落幕。 本次大赛共有508个项目报名参赛&#xff0c;经过4个…

springboot中的异步任务

在springboot项目中可以通过EnableAsyncAsync的方式简化异步操作&#xff0c;下文使用springboot:3.2.1 源码分析 若一个bean中的公共方法上标注了Async&#xff0c;在系统启动时&#xff0c;会给这个类创建一个代理对象&#xff0c;并将该代理对象作为bean注册到spring容器中 …

PyTorch 模型调试与故障排除指南

在当代深度学习领域&#xff0c;PyTorch 已成为开发和训练神经网络的主要框架之一。然而随着模型复杂度的增加和数据规模的扩大&#xff0c;开发者常常面临各种调试和优化挑战。本文旨在为 PyTorch 开发者提供一个全面的调试指南&#xff0c;涵盖从基础概念到高级技术的广泛内容…

2024双11买什么东西比较好?2024双十一好物推荐

双十一各种爆款商品&#xff0c;打折商品非常多&#xff0c;容易让人挑花眼也容易落入消费主义的陷阱&#xff0c;买回家后发现并不实用&#xff0c;甚至可能是自己平常生活中根本用不上的东西&#xff01;即使是打折活动也要在购买前考虑一下自己是否需要&#xff0c;在日常生…

DAMODEL——创建云实例与部署深度学习模型的详细指南

使用 DAMODEL 控制台创建云实例与部署深度学习模型的详细指南 本文将逐步介绍如何使用 DAMODEL 控制台创建云实例、配置 SSH 密钥、上传与下载数据集、以及基于 UNet 网络进行眼底血管分割的完整流程。此指南适用于需要在云端进行深度学习训练的用户&#xff0c;提供详细的操作…

YOLOv10改进,YOLOv10主干网络替换为FasterNet(全网独发手把手教学,助力涨点)

摘要 近年来,许多研究致力于减少浮点运算(FLOPs)以加速神经网络。然而,我们观察到这种FLOPs的减少并不一定能带来相应的延迟减少。这主要是由于运算每秒浮点运算数(FLOPS)效率低下,尤其是在频繁的内存访问(如深度卷积)时。为了解决这一问题,提出了一种新的部分卷积(…

如何快速上手一个Github的开源项目

程序研发领域正是有一些热衷开源的小伙伴&#xff0c;技能迭代才能如此的迅速&#xff0c;因此&#xff0c;快速上手一个GitHub上的开源项目&#xff0c;基本上已经变成很个程序员小伙伴必须掌握的技能&#xff0c;因为终究你会应用到其中的一个或多个项目&#xff0c;帮助自己…

<刷题笔记> 二叉搜索树与双向链表注意事项

二叉搜索树与双向链表_牛客题霸_牛客网 (nowcoder.com) 根据题意&#xff0c;我们需要将搜索二叉树转换成有序的形式。 重点一&#xff1a;BST的中序遍历一定是有序的 因此&#xff0c;此题无论如何都需要使用中序。 又因为要求原地算法&#xff0c;所以&#xff1a; 重点二&a…

Oracle AI理论与实践,企业落地篇干货满满

最近也是看到了圈子里的一位DBA好友&#xff0c;领导安排的工作是让负责AI的落地&#xff0c;而且也作为他业绩考核的指标&#xff0c;作为1名15年的DBA老兵来说&#xff0c;让AI落地面临的困难重重。 AI已经逐渐侵入到实际的生活中&#xff0c;最近我也是参加了Oracle官方在中…

大模型下载、本地部署和调用攻略

零、下载大模型——以Qwen/Qwen2.5-7B为例 1、下载前的准备工作 1.1 仔细阅读模型的Model card介绍 里面会有支持的上下文长度、模型结构、参数量等基本信息 1.2 查看模型文件 Tokenizer相关的文件&#xff1a; merges.txt&#xff1a;这是用于Byte Pair Encoding&#xff…

git笔记之重置本地仓库所有分支和远程保持一致、工作区恢复干净,像刚clone下来一样

git笔记之重置本地仓库所有分支和远程保持一致、工作区恢复干净&#xff0c;像刚clone下来一样 code review! 文章目录 git笔记之重置本地仓库所有分支和远程保持一致、工作区恢复干净&#xff0c;像刚clone下来一样1.实现该功能的 Bash 脚本示例2.改进版&#xff1a;增加了gi…

【第十八章:Sentosa_DSML社区版-机器学习之协同过滤】

【第十八章&#xff1a;Sentosa_DSML社区版-机器学习之协同过滤】 1.算子介绍 协同过滤是推荐系统中常用的一种方法。该算法旨在填补用户-产品关联矩阵中缺少的项。在算法中&#xff0c;用户和产品都是通过一组少量的潜在因素描述&#xff0c;这些潜在因素可以用于预测用户-产…