Linux的进程信号(上)

news/2024/11/30 2:50:01/

在这里插入图片描述

文章目录

  • 1. 信号入门
  • 2. 技术应用角度的信号
  • 3. 信号概念
  • 4. 信号处理常见方式
  • 5. 产生信号
    • 5.1 通过终端按键产生信号
    • 5.2 调用系统函数向进程发信号
    • 5.3 由软件条件产生信号
    • 5.4 硬件异常产生信号
  • 6. Core Dump

1. 信号入门

在生活中,比如红绿灯,铃声这些,首先,我们肯定是知道这些东西和它所表示的含义,也就是说我们能识别这些信号
第二,红灯停,绿灯行,即便当前信号还没有产生,我们已经提前知道这个信号的处理方法

对应到进程
信号是给进程发送的,所以进程要具备处理信号的能力,那么进程要能够识别对应的信号,并且能够处理对应的信号

对于进程来讲,即使是信号还没有产生,我们进程已经具备识别和处理这个信号的能力了

2. 技术应用角度的信号

1.用户输入命令,在Shell下启动一个前台进程,用户按下Ctrl-C,这个键盘输入产生一个硬件中断,被OS获取,解释成信号,发送给目标前台进程,前台进程因为收到信号,进而引起进程退出。

那么什么是前台进程
前台进程:是在终端中运行的命令,那么该终端就为进程的控制终端,一旦这个终端关闭,这个进程也随之消失

举个例子
在这里插入图片描述
在这里插入图片描述
这里bash被该进程所占据了,不会执行其它进程,这样就叫做前台进程。

那么什么是后台进程
后台进程:也叫守护进程,是运行在后台的一种特殊进程,不受终端控制,它不需要终端的交互
在这里插入图片描述
我们在运行进程时后面加一个&符号就是后台进程。后台进程Ctrl+c不能结束,并且可以运行其它进程。

那么我们如何将一个后台进程给结束掉呢
在这里插入图片描述
我们把打印先给注释了。
在这里插入图片描述
这里的jobs可以看到我们的后台进程,1,2,3代表的是作业号,后面的数字代表的是进程的编号。
在这里插入图片描述
如果我们想退出某个后台进程,我们先fg 作业号,这个意思是它这个进程从后台进程改成前台进程
然后再Ctrl+c退出进程就行了。

如果我们再把后台进程改成前台进程后悔了,怎么办
在这里插入图片描述
我们先Ctrl+z:
在这里插入图片描述
我们可以看到3号的进程变成Stopped了,然后我们bg 作业号
在这里插入图片描述
可以看到这里的作业号又运行起来了。

注意
1. Ctrl+C 产生的信号只能发给前台进程。一个命令后面加个&可以放到后台运行,这样Shell不必等待进程结束就可以接受新的命令,启动新的进程。
2. Shell可以同时运行一个前台进程和任意多个后台进程,只有前台进程才能接到像 Ctrl+C 这种控制键产生的信号。
3. 前台进程在运行过程中用户随时可能按下 Ctrl+C 而产生一个信号,也就是说该进程的用户空间代码执行到任何地方都有可能收到 SIGINT 信号而终止,所以信号相对于进程的控制流程来说是异步的

3. 信号概念

信号是进程之间事件异步通知的一种方式,属于软中断

同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去

异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率

用kill -l命令可以察看系统定义的信号列表:
在这里插入图片描述
这里一共有62个信号,没有32和33信号。前31个信号叫做普通信号,34以上的叫做实时信号,我们需要学习的是普通信号。
每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到,例如其中有定义 #define SIGINT 2

4. 信号处理常见方式

因为信号产生是异步的,当信号产生的时候,对应的进程可能正在做更重要的事,我们的进程可以暂时不处理这个信号,但是我们必须记住这个信号

那么进程是如何记住这个信号的
首先,信号在进程的PCB中会被保存下来。在PCB中有一个uint32_t类型的变量代表了位图。
在这里插入图片描述
比特位的位置不同代表了不同的信号。

当进程空闲时,会如何处理这个信号呢

举个例子:
当外卖来了,你正在打游戏,你让外卖员放外面,当你游戏结束时,你去拿外卖然后吃,这是一个默认动作。或者你打完游戏,忘记了还有外卖。或者你的外卖给其他人吃了,这是自己安排这个外卖。那么进程的处理也是一样的。

1. 忽略此信号。
2. 执行该信号的默认处理动作。
3. 自定义动作

这就叫做信号的捕捉。

5. 产生信号

5.1 通过终端按键产生信号

我们先来学习一个函数:
在这里插入图片描述
第一个参数signum:指明了所要处理的信号类型。
第二个参数handler:我们处理的方式(是系统默认还是忽略还是捕获),这里第二个参数也是一种回调方法

举个例子:
在这里插入图片描述
我们对2号信号进行捕捉,设置完成后,去执行自己的进程。

运行结果如下:
在这里插入图片描述
从运行结果可以看到:当前并没有调用handler方法。
在这里插入图片描述
这里只是设置了一个回调,如果SIGINT信号产生时,该方法才会被调用。如果不产生SIGINT,该方法不会被调用

这里Ctrl+c本质就是给前台进程发送2号信号给目标进程,目标进程默认对2号信号的处理是终止自己。这里我们用函数更改了对2号信号的处理,设置了用户自定义的处理方法

这就是由键盘产生的信号。

注意:9号信号也叫做管理员信号,它永远是默认处理,不会被我们设置

5.2 调用系统函数向进程发信号

在这里插入图片描述
返回值是成功返回0,错误返回-1。第一个参数就是进程的pid,第二个参数就是传递的信号。kill命令是调用kill函数实现的。kill函数可以给一个指定的进程发送指定的信号。

下面我们自己写一个kill命令:
在这里插入图片描述
这里字符串需要转成整型,并且pid_t需要强转。如果kill函数成功了,就向指定的进程发送信号了。

在这里插入图片描述
然后我们再写一个循环的死进程。

运行结果
在这里插入图片描述

我们再介绍一个函数:
在这里插入图片描述
raise函数可以给当前进程发送指定的信号(自己给自己发信号)。
在这里插入图片描述
这里的意思是:自己给自己发送2号信号。
在这里插入图片描述
还有一个函数:
在这里插入图片描述
这个函数是自己给自己发送6号信号。自己终止自己。就像exit函数一样,abort函数总是会成功的,所以没有返回值。
在这里插入图片描述
运行结果:
在这里插入图片描述
虽然说6号信号会被捕捉,但是还是会执行退出。

5.3 由软件条件产生信号

在这里插入图片描述
这个函数的返回值是0或者是以前设定的闹钟时间还余下的秒数

打个比方,某人要小睡一觉,设定闹钟为30分钟之后响,20分钟后被人吵醒了,还想多睡一会儿,于是重新设定闹钟为15分钟之后响,“以前设定的闹钟时间还余下的时间”就是10分钟。如果seconds值为0,表示取消以前设定的闹钟,函数的返回值仍然是以前设定的闹钟时间还余下的秒数。

在这里插入图片描述
这个程序的意思是:一秒能累加多少次。
在这里插入图片描述
我们可以看到它累加了这么多次。但是确定就这么多次吗?
在这里插入图片描述
我们这里设置一个回调函数,当闹钟1s以后,会捕捉这个信号,就可以统计++的次数。
在这里插入图片描述
这是打印的结果,从这也反应出IO是非常慢的。

5.4 硬件异常产生信号

硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。
例如当前进程执行了除以0的指令,CPU的运算单元会产生异常。内核将这个异常解释为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。
在这里插入图片描述
运行结果如下:
在这里插入图片描述
那么崩溃的本质是什么呢
我们可以先捕捉一下信号:
在这里插入图片描述
在这里插入图片描述
除0错误就发送了8号信号。我们再看一下野指针:
在这里插入图片描述
在这里插入图片描述
野指针访问就是发送了11信号。

进程崩溃的本质是:该进程收到了异常信号

过程如下
除零:CPU内部,状态寄存器,当我们出0的时候,CPU内的状态寄存器会被设置成为有报错:浮点数越界,OS就会识别到CPU内有报错。OS就会找是谁干的和是什么报错(OS->构建信号)。然后,OS给目标进程发送信号,目标进程在合适的时候处理信号,终止进程。

越界&&野指针: 我们在语言层面使用的地址(指针),其实都是虚拟地址->物理地址->物理内存->读取对应的数据和代码的。如果虚拟地址有问题,地址转化的工作是由(MMU(硬件)+页表(软件)), 转化过程就会引起问题->表现在硬件MMU上->OS发现硬件出现了问题。OS就会找是谁干的和是什么报错(OS->构建信号)。然后,OS给目标进程发送信号,目标进程在合适的时候处理信号,终止进程。

崩溃了,一定会导致进程终止吗
答案是:不一定。举个例子:
在这里插入图片描述
我们把exit先注释了。
在这里插入图片描述
在这里插入图片描述
我们可以看到这个进程它还在运行中,没有崩溃。

因为原来默认是终止进程,但是现在改成了打印一句话,并没有做任何处理的事。所以异常还在,就会一直打印发送。

6. Core Dump

在进程等待的时候,我们说过status:
在这里插入图片描述
下面我们就把Core Dump打印出来看一看:
在这里插入图片描述
运行结果如下:
在这里插入图片描述
Core Dump为0,我们在看一下除0错误:
在这里插入图片描述
我们可以man 7 signal详细查看信号内容:
在这里插入图片描述
这里每个错误会有对应的动作。Term就是什么都不干,就终止。Core是终止,并且会执行Core Dump。

那么为什么Core Dump会是0呢
在云服务器上,core file size默认是0,也就是关闭。
在这里插入图片描述
我们可以自己设置一下:
在这里插入图片描述
此时,我们再看一下运行结果:
在这里插入图片描述
此时的core就设置成1了。
在这里插入图片描述
但是可以看出它多出来这样一个文件,如果我们打开这个文件,里面是乱码。

那么Core Dump到底是什么呢
当一个进程要异常终止时,可以选择把进程的用户空间内存数据全部保存到磁盘上,文件名通常是core,后面的数字代表的是哪个进程,这叫做Core Dump,也叫做核心转储。
进程异常终止通常是因为有Bug,事后可以用调试器检查core文件以查清错误原因,这叫做事后调试。一个进程允许产生多大的core文件取决于进程的Resource Limit(这个信息保存在PCB中)。默认是不允许产生core文件的,因为core文件中可能包含用户密码等敏感信息,不安全。在开发调试阶段可以用ulimit命令改变这个限制,允许产生core文件。

那么Core Dump有什么用呢
在这里插入图片描述
这是一个非常简单的野指针使用。
在这里插入图片描述
我们把这个编译带上-g选项。
在这里插入图片描述
在这里插入图片描述
它可以帮我们直接定位错误。


http://www.ppmy.cn/news/94020.html

相关文章

每日一题——两数之和(返回下标和返回数值两种情况)

每日一题 两数之和 题目链接 思路 注:本题只采用暴力解法,时间复杂度为O(n2),如果采用哈希表,可以将时间复杂度降到O(n),但由于笔者还未对哈希表展开学习,故不做讨论 我们直接用两层for循环来解决问题 第…

【Python】内置函数

文章目录 反射相关【4】基础数据类型相关【38】和数字相关&#xff08;14&#xff09;数据类型 <4>bool([x])int((x, base10)float([x])complex([real[, imag]]) 进制转换 <3>bin(x)oct(x)hex(x) 数学运算&#xff08;7&#xff09;abs(x)divmod(a, b)round(x [, n…

Scikit-LLM:将大语言模型整合进Sklearn的工作流

我们以前介绍过Pandas和ChaGPT整合&#xff0c;这样可以不了解Pandas的情况下对DataFrame进行操作。现在又有人开源了Scikit-LLM&#xff0c;它结合了强大的语言模型&#xff0c;如ChatGPT和scikit-learn。但这个并不是让我们自动化scikit-learn&#xff0c;而是将scikit-learn…

第三十九章 青格郎当(青衣弹灵诞生)

“巴哥奔&#xff0c;我们诚挚邀请你加入金马弹灵&#xff0c;着青衣&#xff0c;事渲染&#xff0c;你愿意么&#xff1f;” 蓝衣弹灵话音刚落&#xff0c;大家一齐睁开眼睛&#xff0c;直愣愣的盯着巴哥奔。 “唔~~~可~” 好半天&#xff0c;巴哥奔才憋出这个字&#xff0c;刚…

uCOSii任务管理

uCOSii任务管理 主要用来测试uCOSii“创建任务,挂起任务,恢复任务,发送删除任务请求,删除任务”。 在os_cfg.h中 #define OS_LOWEST_PRIO 63u //设置最低优先级为63,则空闲任务优先级OS_TASK_IDLE_PRIO就等于63 //OS_PRIO_SELF为255,因此OS_LOWEST_PRIO<255 注意&a…

定积分的计算(牛顿-莱布尼茨公式)习题

前置知识&#xff1a;定积分的计算&#xff08;牛顿-莱布尼茨公式&#xff09; 习题1 计算 ∫ 0 2 ( x 2 − 2 x 3 ) d x \int_0^2(x^2-2x3)dx ∫02​(x2−2x3)dx 解&#xff1a; \qquad 原式 ( 1 3 x 3 − x 2 3 x ) ∣ 0 2 ( 8 3 − 4 6 ) − 0 14 3 (\dfrac 13x^3-…

Emacs之定制化mode line(第一百零二)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

java基础入门-15-【集合(Map可变参数集合工具类)】

Java基础入门-15-【集合(Map&可变参数&集合工具类)】 24、集合(Map&可变参数&集合工具类)双列集合的特点1.Map集合1.1 Map集合概述和特点【理解】1.2 Map集合的基本功能【应用】1.3 Map集合的获取功能【应用】1.4 Map集合的遍历(方式1)【应用】----- 键找值…