【Linux】信号概念和信号的产生

文章目录

  • 一、什么是信号?
    • 1.signal系统调用
    • 2.从硬件解析键盘数据如何输入给内核
    • 3.同步和异步
  • 二、信号的产生
    • 1.键盘组合键
    • 2. kill命令
    • 3.系统调用接口
      • 3.1kill
      • 3.2 raise
      • 3.3abort
    • 4.异常
    • 5.软件条件
  • 重谈core dump标志位


一、什么是信号?

以日常为例,信号弹,上下课铃声,动物求偶行为,红绿灯等等。这些都是信号。


我们怎么认识信号?
从小开始,父母教的,老师教我们识别这些信号。


在信号产生后,可能我并不会马上处理该信号,但我记得有这个信号。所以必须在未来某个时间窗口内处理该信号。

比如:在宿舍点外卖的行为,外卖员打电话,我当时在打游戏,电话一挂,推高地去了,然后游戏打完后,我再下去拿外卖。
这个就是典型的信号收到之后,没有马上处理,而是再未来某个时间窗口内处理。


对于进程:

  • 1.进程必须具备识别和处理信号的能力。即使没有产生信号,但是也要能够识别对应未来可能产生的信号,属于进程的内置功能。
  • 2.当进程真的收到一个信号的时候,可能并不会立刻处理该信号,会在合适的时候处理。
  • 3.一个进程必须具备一个信号产生,到该信号被处理这个时间窗口内将信号保存的能力。

根据上面第二点,进程处理信号的方式有三种:

  • 默认动作
  • 忽略
  • 自定义动作

提出问题:
ctrl + c为什么能够杀掉前台进程呢?

前台进程:
在Linux中,一次登陆中,一个终端配一个bash,每一个登陆,只允许一个进程是前台进程。

也就是说,我们的bash,输命令的进程,就是前台进程,当写好代码,将一个程序运行起来后,这个正在运行的进程就是前台进程,bash就被变成后台进程了。

键盘在输入的时候,是前台进程获取的。

所以一个循环执行的时候,在键盘输入ctrl + c,会被前台进程获取并识别成2号信号,2号信号就是将进程中断。

所以ctrl + c的本质是被进程识别成2号信号。

1.signal系统调用

前面说过,进程处理信号的方式有三种。
对于2号信号来说,进程处理该信号的默认方式就是终止自己。
而其他两种处理方式,就是要signal函数解决。
在这里插入图片描述
第一个参数:signum,几号信号。
第二个函数:这个参数的类型是一个函数指针类型,其实就是自定义的处理signum信号的方式。

也就是说,调用signal系统调用,如果传入2号参数,在将来遇到2号信号时,处理方式就是调用handler函数的自定义处理方式。

void myheader(int sig)
{cout << "process get a signal : %d "<< sig << endl;
}int main()
{signal(SIGINT,myheader);int cnt = 50;while(cnt--){cout << "I am a process" << endl;sleep(1);}return 0;
}

在这里插入图片描述
遇到2号信号时,调用的自定义处理方式就是调用自己写的handler函数。

注意:signal函数只需要设置一次,就一直有效,往后只要遇到2号信号,都会使用自定义处理信号的方式,即调用handler函数。


2.从硬件解析键盘数据如何输入给内核

首先,键盘只要被摁下了,一定是操作系统先知道!

那么,操作系统怎么知道键盘上有数据?

在计算机中有许多硬件,其中,只要我们摁下键盘的键,就会产生信号中断,
通过高低电流的形式发送给中断单元,中断单元再将该信号发送到CPU的引脚,CPU接收到信号后,告知操作系统,并将中断单元号发送给操作系统,操作系统收到信号后,执行中断向量表中对应中断编号的方法的地址。

而再执行读取键盘的方法,也就是将键盘上摁下的内容拷贝到内存中的内核缓冲区中。
至此,就完成了操作系统可以知道键盘上有数据并将数据拷贝到内核缓冲区中的动作。

在这里插入图片描述

所以,操作系统不需要再对每一个硬件进行信号的检测了,只需等待CPU将对应的中断信号发送过来即可。


在这里插入图片描述

对于上面这种后台进程输入了l,再输入s,但是在屏幕上显示的是乱序的问题。

其实原理如下:

键盘在被摁下的时候,按键被加载到缓冲区中,第一次摁下l键,此时键盘缓冲区中有一个l键,然后再将该字符拷贝到显示器缓冲区中,打印到显示器上,此时后台进程一直再跑,也将对应的字符串打印到显示器上,造成打印是乱序的。
但是丝毫不影响键盘缓冲区中的l字符。

因为键盘文件和显示器文件是两个不同的文件,分别具有不同的缓冲区。
他们互不干扰,所以再输入s时,键盘缓冲区就形成了ls指令,再将该s拷贝到显示器缓冲区中打印到显示器文件上,就看到了乱序的ls指令,但是按下回车键后,键盘会向CPU发送硬件中断。就执行了ls命令。

在这里插入图片描述

3.同步和异步

信号的产生和我们写的代码执行是异步的。

就比如说:

我和张三去自习室学习,张三说,等我会宿舍拿本书,然后我就在楼下等张三,等到张三后我们在一起去自习。我们一起去的过程就是同步进行的。
如果我和张三去自习室自习,张三说他去拿书,我不等他,我就先走了,然后我就和张三不同时到自习室,这个过程就是异步的。

二、信号的产生

信号产生的方式有五种。

1.键盘组合键

在这里插入图片描述

  • 1.ctrl + c产生2号信号。
  • 2.ctrl + \产生3号信号。

2. kill命令

kill -signo + 进程pid

对特定进程发送对应的信号。

3.系统调用接口

3.1kill

在这里插入图片描述
给pid进程发送sig信号。

//实现一个kill命令
void Usage(string name)
{cout << "Usage:\n\t" << name << " signo pid" << endl;
}int main(int argc,char* argv[])
{if(argc != 3){Usage(argv[0]);exit(1);}int signo = stoi(argv[1]); //获取信号码pid_t pid = stoi(argv[2]); //获取信号idint n = kill(pid,signo);if(n < 0) //kill 失败了{perror("kill");exit(1);}return 0;
}

3.2 raise

给调用者发送指定的信号。
也就是给自己发送指定信号。

在这里插入图片描述
该函数的本质就是调用kill(getpid(),sig);

3.3abort

给自己发送6号信号。
在这里插入图片描述

该函数的底层就是调用Kill(getpid(),6)

4.异常

当代码出现异常时,会向进程发送信号。

//模拟异常后发信号
void handler(int sig)
{cout << "receive " << sig << " signo!"<<endl;sleep(1);
}int main()
{signal(SIGFPE,handler);int a = 10;a/=0;return 0;
}

在这里插入图片描述
这里有个问题:信号为什么一直被触发?操作系统怎么知道进程发信号了?

在这里插入图片描述
CPU内的寄存器eip/pc会记录进程中的代码走到哪一步了。
CPU中有一个寄存器叫做状态寄存器,这个状态寄存器虽然也是寄存器,但是该寄存器被设置成了具有比特位的寄存器,也就是说一个寄存器可以表示多个状态。

这些状态寄存器,eip寄存器等等保存的数据,都叫做进程上下文

一个进程在退出时会把关于该进程本身的上下文数据全部带走,下一个进程在被CPU调度执行时,会把自己进程的上下文数据加载到CPU的寄存器中。

所以,上一个进程如果修改了状态寄存器中的内容,也丝毫不影响下一个进程!!!

所以虽然我们修改了状态寄存器的内容,但只影响我进程自己!

所以,当一个进程出现异常时,状态寄存器的某个比特位会由0置1。而操作系统要保证CPU的健康状态,一定会频繁地检查寄存器的内容是否被修改,从而获取到进程是否出异常了!!

CPU也是硬件,操作系统是硬件的管理者!!!

为什么操作系统不直接根据进程发的信号,帮助进程处理这些信号呢?

因为信号存在的意义,就是为了让进程死的明白!!

进程会被操作系统指派去执行各种各样的任务,而这些任务又是用户给的。一旦某个任务在执行过程中出现异常,产生信号了,进程要知道自己到底因为什么而产生的信号,这样就算自己死了也能给上面一个交代!

异常的出现只是为了可以统一在一个地方处理后续的工作,而不是用来解决的。

异常无法解决,只能让用户知道到底是什么原因而改变相应的策略。

5.软件条件

软件条件实现闹钟

alarm函数实现闹钟。
在这里插入图片描述

设置一个函数实现闹钟,seconds秒之后会响,然后向进程发送14号信号终止进程。
返回值是:上一次设置的闹钟的剩余时间。

如果第一次设置闹钟是10秒,过了5秒后,再设置一个闹钟,此时设置的第二个闹钟时,返回值就是第一个闹钟的剩余时间,也就是5。

void handler(int sig)
{cout << "receive a " << sig << " signal" << endl;
}int main()
{signal(SIGALRM,handler);int n = alarm(5);while(true){cout << "i am a process ,pid : " << getpid() << endl;sleep(1);}return 0;
}

该代码验证了闹钟响,并向进程发送14号信号的结论。


重谈core dump标志位

在这里插入图片描述
在进程等待环节中,进程等待的中的status参数的其中一个比特位叫做core dump标志位

这个比特位的意义是:
一旦进程出现异常,OS会将进程在内存中的运行信息,给我转储(转而存储,dump)到进程的当前目录(磁盘)形成core.pid文件,这个过程叫做核心转储。
并将core dump对应的比特位设置为1,告诉用户。
为什么要有core dump这个功能呢,这是为了方便进行事后调试,也就是代码出错后再调试。

使用

ulimit -a查看系统的一些配置,其中第一个就是core file size,core文件的大小为0,说明core功能未打开
使用
ulimit -c 10240,将core文件大小设置最大为10240字节,此时就相当于打开了core功能了。

在这里插入图片描述

在.cc文件中写代码写一个除零错误后,会发现结果如下
在这里插入图片描述

那就意味着进程出现异常后,生成了一个core.pid文件,就是把进程在内存的运行信息转储到当前进程的目录下。

打开调试器调试当前可执行程序后,在这里插入图片描述
结果如下,将core.pid文件导入后,就能看到具体错误出现在什么地方,这样的调试就是事后调试

其中,默认的云服务器没有打开core dump功能。

因为在公司的服务器中,如果某个服务挂掉了,不管三七二十一,先不管为什么挂掉,立刻进行重启,立刻重新启动服务,事后再根据日志其他的排查问题即可。可是,如果打开了core dump功能,每次有服务挂掉,都会形成一个core.pid文件,这个文件还挺大的,如果在某个时间段,有许许多多的服务挂掉,或者一个服务挂了之后重启,重启后又挂掉,这样重重复复会产生大量的core.pid文件,久而久之会将磁盘空间占满,这时候就不再是服务挂掉那么简单的问题了,可能就转变成了操作系统挂掉的严重问题!

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

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

相关文章

Elasticsearch:么是向量嵌入?

向量嵌入定义 向量嵌入 (vector embeddings) 是一种将单词、句子和其他数据转换为捕获其含义和关系的数字的方法。 它们将不同的数据类型表示为多维空间中的点&#xff0c;其中相似的数据点更紧密地聚集在一起。 这些数字表示可以帮助机器更有效地理解和处理这些数据。 单词和…

VS安装QT VS Tools编译无法通过

场景&#xff1a; 项目拷贝到虚拟机内部后&#xff0c;配置好相关环境后无法编译&#xff0c;安装QT VS Tools后依旧无法编译&#xff0c;查找资料网上说的是QT工具版本不一致导致的&#xff0c;但反复试了几个版本后依旧无法编译通过。错误信息如下&#xff1a; C:\Users\Ad…

OpenTelemetry系列 - 第1篇 相关概念

目录 一、背景二、概念2.1 Traces & Span2.2 Metrics2.3 Logs2.4 Baggage2.5 OTel2.6 OTLP2.7 Resources2.8 Instrumentation Scope2.9 Sampling 三、核心组件 一、背景 OpenTelemetry是一个可观察性框架和工具包&#xff0c;旨在创建和管理遥测数据&#xff0c;如跟踪、指…

Monocle 3 | 太牛了!单细胞必学R包!~(五)(差异分析之聚类比较与模块鉴定)

1写在前面 准备出去玩耍了&#xff0c;今天就不废话了&#xff0c;直接上主题吧。&#x1f973; monocle3做差异分析也是牛的一米&#xff01;~&#x1f33e; 2用到的包 rm(list ls())library(tidyverse)library(monocle3) 3示例数据 我们还是载入之前用过的一个数据集吧。&am…

HarmonyOs 4 (三) ArkTS语言

目录 一 认识ArkTs语言1.1 ArkTs1.2 基本结构 二 基本语法2.1 声明式UI2.1.1 创建组件2.1.1.1 无参数2.1.1.2 有参数2.1.1.3 组件样式2.1.1.4 组件方法2.1.1.5 组件嵌套 2.1.2 自定义组件2.1.2.1 基本结构2.1.2.2 成员函数/变量2.1.2.3 自定义组件的参数规定2.1.2.4 Build函数2…

高效转码工具Compressor for Mac,让视频处理更轻松

在现如今的数字时代&#xff0c;视频内容已经成为人们生活中不可或缺的一部分。无论是在社交媒体上分享生活点滴&#xff0c;还是在工作中制作专业的营销视频&#xff0c;我们都希望能够以高质量、高效率地处理和传输视频文件。而Compressor for Mac作为一款强大的视频转码工具…

vivado实现分析与收敛技巧6-策略建议

典型时序收敛策略需运行大量实现策略并选取其中最佳的策略以供在实验室内应用。 ML 策略同样可选 &#xff0c; 且只需您运行3 项策略即可达成类似的 QoR 收益。这些策略使用机器学习来检验布线后设计的各项功能特性 &#xff0c; 以便预测相同设计上不同策略的性能。在 repo…

unity3d c#代码变更文本颜色,可选多参数,委托invoke延迟调用函数

[SerializeField] private Text warning; Color color ;warningOpen("注册成功", closeTime: 1.5f);warningOpen("登录成功", "green", 1.5f);public void warningOpen( string warn, string tmp"red", float closeTime5f ){warnin…

常用装备生产ERP有哪几种?有哪些作用

装备生产业务涉及原材料采购、车间排产、班组生产评估、派工单、接单报价、委外发料、库存盘点、设备台账、图纸设计等诸多环节&#xff0c;而各环节数据的共享问题普遍存在于装备生产企业内部&#xff0c;同时也直接影响企业的生产效率和整体效益等。 企业外部环境的变化和行…

探索意义的深度:自然语言处理中的语义相似性

一、说明 语义相似度&#xff0c;反应出计算机对相同内容&#xff0c;不同表达的识别能力。因而识别范围至少是个句子&#xff0c;最大范围就是文章&#xff0c;其研究方法有所区别。本文将按照目前高手的研究成绩&#xff0c;作为谈资介绍给诸位。 二、语义相似度简介 自然语言…

特种电源模块怎么测试?用电源模块测试系统测试需要哪些流程?

什么是特种电源? 特种电源即特殊种类的电源&#xff0c;是能够为各种特殊场合或应用提供稳定、可靠电力的电源设备。特种电源的特殊性主要体现在输出电压特别高&#xff0c;输出电流特别大&#xff0c;对稳定度、动态响应及纹波要求特别高等。 根据应用场景和功能&#xff0c;…

什么是Anaconda

Anaconda的安装也很方便。打开这个网站Anaconda下载&#xff0c;然后安装即可。 Anaconda可以帮助我们解决团队之间合作的包依赖管理问题。在没有使用Anaconda之前&#xff0c;如果你的Python程序想让你的同事运行&#xff0c;那么你的同事可能会遇到很多包依赖问题&#xff0…

景联文科技数据标注平台助力AI数据实现价值最大化

随着人工智能技术不断进步&#xff0c;应用领域不断拓宽&#xff0c;对于高质量、大规模标注数据的需求也在不断增加。 数据标注是人工智能行业的基石。机器学习需要运用海量的有效数据来做支撑&#xff0c;而这些数据就需要我们的标注员对其进行分析和处理&#xff0c;想要得到…

系列十七、理解SpringBoot中的starter 自定义一个starter

一、概述 作为后端Java程序员&#xff0c;基本上公司的日常开发都是基于SpringBoot进行的&#xff0c;我们使用SpringBoot也是沉醉于它的各种各样的starter带给我们的便利&#xff0c;这些starter为我们带来了众多的自动化配置&#xff0c;通过这些自动化配置&#xff0c;我们可…

c语言-快速排序

目录 一、实现快速排序三种方法 1、hoare法 2、挖坑法 3、双指针法 4、快速排序的优化 5、测试对比 结语&#xff1a; 前言&#xff1a; 快速排序作为多种排序方法中效率最高的一种&#xff0c;其底层原理被广泛运用&#xff0c;他的核心思想与二叉树结构中的递归逻辑相似…

30秒搞定一个属于你的问答机器人,快速抓取网站内容

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 文章目录 简介运行效果GitHub地址 简介 爬取一个网站的内容&#xff0c;然后让这个内容变成你自己的私有知识库&#xff0c;并且还可以搭建一个基于私有知识库的问…

没有预装Edge浏览器的Windows系统安装Edge正式版的方法,离线安装和在线安装

一、在线安装 没有预装Edge浏览器的Windows系统安装Edge正式版的方法 二、离线安装 进入到下面这个目录 C:\Program Files (x86)

【Web】NISACTF 2022 个人复现

目录 ①easyssrf ②babyupload ③ level-up ④bingdundun~ 明天就新生赛了&#xff0c;练套题保持下手感吧 &#xff08;文章只选取了一部分&#xff09; ①easyssrf 输入/flag 输入file:///fl4g 访问/ha1x1ux1u.php ?filephp://filter/convert.base64-encode/resource/…

C++利剑string类(详解)

前言&#xff1a;大家都知道在C语言里面的有 char 类型&#xff0c;我接下来要讲的 string 类功能是使用 char 类型写的类&#xff0c;当然这个是C官方写的&#xff0c;接下来我们将会学会使用它&#xff0c;我们会发现原来 char 这种类型是还能这么好用&#xff0c;授人以…

【VerilogVCS仿真_2023.11.15】

HDL&#xff1a;硬件描述语言&#xff0c;并发&#xff0c;时序RTL&#xff1a;寄存器传输级语言 Verilog和VHDL的区别&#xff1a;VHDL侧重于系统级描述——系统级设计人员所采用&#xff0c;Verilog侧重于模块行为的抽象描述——电路级设计人员 前端&#xff1a;系统级、算法…