【Linux信号】Linux进程信号(上):信号产生方式和闹钟

🎬 个人主页:艾莉丝努力练剑
❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》
《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》
⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平
🎬 艾莉丝的简介:
文章目录
- 1 ~> 理解信号是什么,为什么要有?生活中的信号
- 2 ~> 信号的产生
- 结尾
1 ~> 理解信号是什么,为什么要有?生活中的信号
1.1 信号是什么?
1.1.1 普通信号和实时信号
- 用
kill -l可以查看
常用的只有1~31,34~64,没有0号——一共62个,不是64个哦!
前31个是普通信号,后面带RT(real-time)实时信号。我们只考虑1-31就好了。
1.1.2 信号的本质
什么是通知?什么是异步?
- 通知:这个通知需要我们理解一下——事件通知。
- 异步:通知的到来,跟我不同步。
举个例子,我点了个外卖,然后就打游戏,外卖小哥送货上门,敲门是一个通知,说明外卖到了,我和外卖小哥是不同步的。
异步关系就是没关系(你做你的,我做我的);同步关系就是有关系(我得等你做完再做)。
- 再比如,比如我是一个老师,我讲课,突然快递电话打过来了,我叫张三去帮我取快递,但是我等张三找完快递回来再继续讲,这就是个同步的关系,张三不回来,我就不往下讲。
- 如果我继续讲课,张三也在找快递,我讲课、他帮我办事,这个就是个异步的关系——我讲我的课,张三找他要帮我找的快递。
1.2 生活中有哪些信号?以及一些结论总结
大抵有如下这些:
上面这些所有的信号产生的几乎都是异步的。
- 人能够识别对应的、甚至还没有发生的这些信号
为什么能够识别这些信号?
人是经过教育的,早就知道信号对应处理动作的对应关系。
操作系统给目标进程发送信号,目标进程能不能识别呢?
- 答案是:进程天然能够识别——进程和信号都是程序员写的代码(进程相当于我们人,已经被程序员教育过了,程序员设计好了)
进程能够识别信号,并且已经知道怎么处理信号了。
1.2.1 man 7 signal:查看信号部分的内容
man 7本身不是查看信号的指令,而是指定要查看的手册章节为第 7 章。在 Linux 系统中,信号相关的概述通常位于第 7 章,因此要查看信号的详细信息,可以使用命令:
man7 signal 会显示信号的概念、列表、默认行为等全局说明。此外,信号相关的系统调用(如 signal()、sigaction())一般在第 2 章,库函数(如 sigsetops())可能在第 3 章,而第 7 章主要提供更上层的概述和标准约定。
1.2.2 信号没有产生也知道怎么处理
1.2.3 收到一个信号会立即处理它吗?
当我们收到一个信号,准备处理这个信号,这里的我们即进程,会立即处理这个信号吗?有时候中断不了呢!处理不了信号。
- 对于信号的处理——不会立即处理——信号可能会立即处理,只有合适的时候会处理。
既然有一定概率不会立即处理,那么得要有把信号临时保存起来的能力——不会立即处理,就得有临时保存的能力。
比如外卖小哥打电话,答应去取外卖之后如果没有保存信号,是不是就打游戏打着打着就忘了取外卖了。
1.2.4 信号怎么处理?
- 默认:我后面打完游戏去拿外卖回来吃
- 忽略:我直接就不想拿了(但是并不是忘了,只是不想)
- 自定义:比如我拿完外卖直接丢了或者干别的事,自定义行为
我们就以红绿信号灯为例:
- 红灯——自动停了——默认信号。
- 收到信号,也处理了,但是处理的方式是忽略——忽略信号。
- 红灯亮了,别人要么忽略要么停下,而你在跳舞——自定义信号。
1.2.5 总结一些这些小结论
- 设别信号是内置的,进程能自己识别信号,是内核程序员写的内置特性。
- 信号的处理方法,在信号产生之前就已经准备好了。
- 处理信号不是立即处理的,因为我可能正在做优先级更高的事情,会选择合适的时候进行处理。比如我在打游戏,外卖员给我打电话叫拿外卖,那我肯定是先忙完手头的事再去拿。
- 信号不会被立即处理,所以就注定了进程要有临时保存信号的能力!
- 信号处理的动作有三种:默认、忽略、自定义,后续都叫信号捕捉。
1.2.6 图示
1.3 信号具体化
1.3.1 为什么是大写?这些大写的名字是什么?
没有0号信号,我们知道,信号是有编号的。
- 这些大写的名字是什么呢?这些大写的名字就是宏。
1.3.2 头文件(含内核查看)
我们查看内核——
1~31是普通信号,我们现在是分时操作系统;34~64是实时信号(有RT,就是real-time)。
1.3.3 保存信号
1.3.3.1 进程一定要有临时保存信号的能力
进程一定要有临时保存信号的能力——原因我们前面已经分析了。
- 信号就是个数字吗?还不够具体。
- 进程需要使用特定的数据类型来保存对应的信号!
我们要分析两个问题——
- 1、我们要保存什么信号?哪一个信号?
- 2、我们要保存信号的侧重点?哪一个信号是否产生了?
1.3.3.2 我们可以用什么样的特定的数据类型来保存信号?位图
- 1、比特位的位置表示信号编号
- 2、比特位的内容要么是1要么是0,1或者0——是否收到对应的信号!
用位图表示对应的1~31个编号。
关键是这个位图在哪里?
- 这个位图应该在哪里?设计在
进程的PCB里面。
1.3.4 信号的位图在进程PCB里面,谁有资格修改内核数据结构中的字段?
- 信号的位图在进程PCB里面,谁有资格修改内核数据结构中的字段?
- 谁有资格——这个世界上,能够给进程写入信号的家伙只有一个——就是操作系统OS。
操作系统不能决定全部的往进程写入信号(有能力,但是也只是一个办事的)——用户让你办的!
- 用户通过系统调用让操作系统向目标进程发送信号。
1.4 为什么要有信号?
- 我们一看到问为什么,一定要想到没有这个东西会出现怎么样的问题。
Linux之所以需要信号,是为了提供一种 异步且轻量级的进程间通信与事件通知机制,使操作系统能够立即打断进程的正常执行流,以通知其发生了诸如用户中断(Ctrl+C)、硬件异常(段错误)、定时器到期或子进程退出等突发状况。信号机制弥补了管道或共享内存等同步通信方式的不足,让进程能够以一种统一、即时的方式响应外部与内部的高优先级事件,是实现进程控制、异常处理和系统紧急交互的核心基础。
1.5 信号是什么的思维导图
如下图所示:
1.6 如何自定义捕捉信号?
一个函数,我们写一段代码——
- 对任何信号进行一下捕捉!
man signal 信号是发给进程——处理信号是进程自己去处理的。
回调函数
signal函数其实是对指定信号未来进行自定义处理的一种延时设定。
我们挑一个信号——这里挑选2号信号:SIGINT
运行一下:
kill-2[pid]- 查看信号手册:
我们在手册(man 7 signal)里面查看2号信号——
要让2号信号不要终止进程,调用我自定义的方法——
这就叫做信号捕捉。
Ctrl C(就是给前台发送2号信号)也终止不了了
我们修改一下代码:
- 信号最终是由进程自己去处理的,通过上面的代码可以验证——两个pid一样
对某个信号进行设定,那这个参数sig是什么?
我们继续验证一下:
本来就是设定了是2号信号,为什么还要把2号信号传进来呢?
- Linux内部,不同的的信号捕捉的处理方法可以是同一个!
所以我们得知道是哪一个信号——我们多个信号设置处理方法,可以是同一个处理方法。
我们再来验证一下:
可以通过传入的参数来区分是哪个信号触发了自定义捕捉。
IGN的参数是1:
我们验证一下:
- 所有的2号信号都被忽略了!
- 还有一种是恢复默认:
SIG_DFL
我们再运行一下:
- 符合预期,就是进程终止,说明恢复默认了!
代码跑完对还是不对由退出码决定。
- 运行一下我们发现,进程果然就杀不掉了!
虽然1~31都能够设定自定义捕捉,但是有两个信号是不能够设定的:9号信号和19 / 20号新号(看系统,具体是哪个)
- 9号信号很重要:9号信号不能被自定义捕捉、不能被忽略。
2 ~> 信号的产生
- 让OS给目标进程写信号。
操作系统给目标进程写信号——不管怎么样,必须经过操作系统——因为只有操作系统能够有资格修改内核数据结构。
产生信号这个话题内容有点多。信号的产生是异步产生的,所以不会立即处理。
2.1 信号产生的方式
2.1.1 使用系统命令产生,kill命令
在【自定义捕捉信号】那里我们已经见识过了。
2.1.2 通过键盘产生信号
放开循环:
我们运行一下:
我们查看手册,来一一对应一下,看看它对于当前进程的处理动作:
- term和core都是进程终止
Ctrl C证明我们可以通过键盘产生信号(组合键的方式)。
- 为什么你如果启动一个进程之后,
Ctrl C可以终止这个进程!Ctrl C:发送了2号信号,2号信号的处理动作是终止! - 我们保留一个问题:键盘怎么能够向目标进程发送信号呢?
键盘是个硬件啊,进程是个软件啊,怎么发送信号?
2.1.3 产生信号的还有一种方式:系统调用
kill:发送信号给进程。
第一个参数:发送给哪个进程;第二个参数:发送哪个信号。
系统底层肯定要调用这个kill。
- 管道那里有一个对应的命令:
mkfifo
Stat:获取函数的属性
printf:底层也是调用了同名系统调用
很多命令底层用到了它的同名系统调用!
我们来测试一下——
- 输出参数不匹配,就给你打印一个使用手册,类似于平常编译时候的报错
- 类型要转成整数
然后就可以使用kill系统调用,向目标进程写入信号——
运行一下,我们发现多了个\n(左边黄色框框):
我们再修改一下源代码:
把\r都去掉
我们再运行,还是前面的那种运行的图,这次我们看本次运行的结果:
kill命令底层调用了kill系统调用——让操作系统向目标进程发送指定信号。
- 如下图,验证了9号信号不能被捕捉
raise:自己给自己可以发任何信号- 修改代码,让进程自己给自己发送信号
- 自己给自己发,1秒打一次——
一个系统调用可以给自己发送任意信号。
raise底层封装了kill
abort
我们修改一下代码,加入abort函数:
- 运行:当前进程立即终止了
我们发现信号是6号信号!
abort:也是Core(终止进程)
6号信号通常用来进行异常终止。
既把信号捕捉了,进程也终止了。
- 6号信号还很特殊:可以理解为不可以被捕捉
可以设置捕捉动作,但是最后还是会终止进程!——异常。
- 6号信号也可以被算做是不能被捕捉、忽略的
2.1.4 第四种产生信号的方式:异常
获取到哪个信号呢?
- 我们放开信号捕捉
- 运行
信号捕捉函数一直被触发(不是因为while循环)——死循环。

- 杀掉进程

11号信号——

- 证明不是因为while(true)循环
照样还是死循环:

我们故意来一个/0错误:
- 8号信号:SIGFPE(浮点异常)
尽管名字包含“浮点”,但它实际上涵盖了更广泛的算术错误,包括整数运算中的错误。
观察一下:
除零错误会被当做信号发出来。
进程自己就会收到对应的信号!
为什么会把进程异常当成信号?进程异常是如何被OS识别、并且解释成为信号的?!
2.1.5 第五种信号产生的方式:由软件条件产生信号
这里就有点抽象了。
- 管道:r端关闭,W端打开,W端一直写 --> OS就会把写进程直接就杀掉了
操作系统认为管道不具备写条件——OS就把写进程杀掉了。
你得罪了软件或者硬件,操作系统都要把你杀掉。
进程退出一定是异常了,收到信号了。
关于闹钟(alarm)的相关话题我们在2.4细说。
2.2 三个系统调用层层递进
2.2.1 三个系统调用层层递进
前面的kill、raise、abort三个系统调用我们发现是层层递进的!
2.2.2 OS先收到键盘输入,再由操作系统转换成信号发送给目标进程
接下来,先不往后面看,先复盘一个问题:
我们已经说过啦,必须只能是OS!
只有操作系统可以在内核操作系统里面对PCB内部的位图进行修改。
换句话说,通过键盘产生信号也并不是键盘直接产生的信号,必然是OS先收到键盘
的输入的,再由操作系统转换成信号发送给目标进程!
2.3 键盘怎么能够目标进程发送信号呢?
- 1、如何理解键盘输入?
键盘是基于硬件中断来进行工作的! - 2、OS如何解释快捷键?(组合键)
ctrl c、ctrl \,……可能会直接解释成为信号! - 3、OS怎么知道信号应该发送给哪一个进程呢?操作系统怎么知道?要补充一点网络时要用的知识!
2.3.1 如何理解键盘输入?
如何理解键盘输入?
我们通过图来理解一下——
我的操作系统怎么知道用户把键盘按下了、按下了哪个(键)字符?——驱动去处理的。
我们关心的是,OS怎么知道键盘上有数据了?!
计算机的外设很多,操作系统要做各种工作,你能够轮询吗?这种做法在技术上可以实现,但是这会让操作系统变得很慢!
硬件中断
作为CPU,只要被动等待就行。
- 中断:是计算机组成原理的最重要的重点,没有之一!没有学懂中断,就是没有学懂操作系统。
操作系统有些东西没有学懂,问题可能不在操作系统上面,可能是在理解计算机组成原理上。
- 跨学科学习是一个比较重要的思路
除了冯诺依曼告诉我们的外设,还有……
键盘和CPU是一根线上连着的。
- 针脚如下所示(英特尔的):会和主板相连。
这些针脚会和主板连上,所以主板走线会和外设勾连。
网卡的例子。
告诉CPU,数据已经到来了,触发中断。
操作系统并不知道键盘上有数据了,而是中断告诉CPU了。
2.3.2 OS如何解释快捷键?
键盘的字符既有“ABCD……”这样的正常的字符,也有“Ctrl C”“Ctrl V”……这样的组合键,操作系统会把组合键解释成信号(会判断,ctrl c是特殊字符,在ASCII码表里存在)——操作系统会有系统调用:给目标进程发送信号——kill(pid,signum)。
2.3.3 OS怎么知道信号应该发送给哪一个进程呢?
- 说到这个,我们先要谈一个进程组和作业的话题。
如下图,我们这里创建了三个进程:
三个进程的父进程都是同一个:bash;即这三个进程是兄弟进程。
2.3.3.1 进程组
- 进程是有组的概念
2.3.3.2 会话ID:SID
这三个兄弟进程的SID一样,属于同一个会话,以bash进程命名:
一般情况下,同一个组里面大家会使用同一个终端文件(因为我们是远程登录的Xshell,这里的终端文件是虚拟网络文件)。
每一个用户登录,都要建立会话,打开终端文件。
如果在bash命令行里再启动一个进程
- 我们把代码改一下,把abort注释掉
同一个终端下,在创建一个进程——
我们发现这个进程和那三个进程不在一个进程组里面,但是在一个会话组里。
本质是一个会话里面创建一个新的进程组(哪怕进程组只有我一个进程)。
- 我们把for循环也注释掉,方便
ctrl c等操作
2.3.3.3 前台进程和后台进程 + 前后台进程切换
进程分前台进程和后台进程:
我们取地址&,就变成后台进程了——
- 我们今天要把这个说法变一变。
我们发现Ctrl C不能干掉进程了——
再看一下:
观察运行的打印结果:
- 我们在代码里面把休眠时间改长一点
前台进程:
后台进程:
我们只能这样删除:
kill-9[pid]- 我们把打印也注释掉,只看到时候的任务号
再创建一大批的任务:
每一个进程都有自己的进程组,都属于同一个会话:
- 启动后台任务,
Ctrl C是杀不掉的!
2.3.3.3.1 前台进程
定义:占用当前终端,必须等该进程执行完毕才能输入其他命令。
示例:直接执行 sleep 100,终端会被占用 100 秒,无法输入新命令。
2.3.3.3.2 后台进程
定义:在后台运行,不占用终端,用户可继续执行其他命令。
启动方式:在命令末尾加 &。
sleep100&输出会显示作业号 [1] 和进程 PID。
2.3.3.3.3 作业控制命令
1 jobs
jobs查看当前终端中的后台作业列表(带作业号)。
输出示例:
[1]+ Running sleep100&2 fg(foreground)
将后台作业调回前台继续运行。
fg %1 # 将作业号 1 的作业调到前台fg# 默认将最近一个后台作业调到前台3 bg(background)
将暂停(挂起)的作业放到后台继续运行。
- 先用
Ctrl+Z暂停前台进程,此时作业变为“已停止”状态。 - 执行
bg %1让它在后台继续运行。
sleep200# 执行,然后按 Ctrl+Z 暂停bg %1 # 在后台继续运行jobs# 可看到状态变为 Running4 Ctrl+Z
暂停当前前台进程,将其放入后台(停止状态)。
5 Ctrl+C
终止前台进程。
进程可以在前台或后台运行,并通过 fg 和 bg 命令进行切换

2.3.3.4 一些结论
结论1:Ctrl C只能用于终止前台进程!
Ctrl C只能用于终止前台进程!
作业 / 独立的进程组有什么关系?

进程组是用来完成作业的!
进程组允许是一个进程。
作业是由进程组完成的!
在命令行./进程(启动一个进程)属于上面所说的特殊情况。
task(作业 / 任务)——进程组和作业就像是硬币,一体两面。
如下图所示:
会话与进程组(作业)的作业之间的关系?
会话内部至少包含一个进程组(就是bash)。
会话: 是由一个或者多个进程组构成的 进程组的集合,通常会有属于自己的终端文件!
通过 **fg [任务号]**把后台任务变成前台之后,就可以Ctrl C删掉了。
在一个会话中,任何时刻,只允许一个进程(组)在前台!
只要一个进程在前台,我的命令就没法被其它进程执行了。
这里存在两个问题:
- 1、为什么其他命令就无法执行了?
因为在一个会话中,任何时刻,只允许一个进程(组)在前台,能够接受、执行命令的bash在哪里?自动切换成为后台进程组了(为什么bash变成后台了,命令就无法进行了)!获取不到命令,就无法执行命令了!
键盘只有一个,在会话里有这么多进程,谁拥有键盘,谁就是前台进程。
- 2、什么叫做前后台?
- 能够直接获取用户输入的基础,叫做前台进程;
- 否则叫做后台进程
因为键盘只有一个,任何时刻只允许一个人输入(只有一个人,一个输入),谁拥有终端文件(主要是键盘),谁就是前台!获取不到键盘,所以就无法输入了。
- 终端文件:键盘和显示器的集合体
后台进程可以写数据(向显示器打印),但是后台进程无法从键盘读取数据(读取的时候会被系统直接暂停掉)。
这就叫做 【会话管理】!
任何时刻,前台进程(组)只有一个!
- 键盘输入:操作系统怎么知道要把信号发送给谁?
前台进程只有一个,所以操作系统知道未来要把信号发给哪个进程!
只能发送给前台进程(组),而且前台进程只有一个!
前后台切换就像是 “孔融让梨”。
- Ctrl C严格意义上不是杀掉一个进程,而是杀掉一个进程组。
父进程子进程都被Ctrl C杀掉了。
登录两次、三次、……系统是不是每次都要创建这些东西?
剩下的,在网络讲【守护进程】的时候再介绍。
后台不允许获取
代码再重编一下:

把前台进程被暂停了,前台进程就会自动切换到后台进程。
- 这里证明了,后台进程能够打印、但是不能获取,一旦获取就会暂停。
- 谁拥有键盘,谁就是前台;谁能够获取键盘的输入,谁就是前台。
当你按键盘一定是和某个会话或者某个终端相关联。
2.4 alarm:设置一个若干秒之后的闹钟
学习一个新的函数:alarm。
再认识一个信号:14号信号。
操作系统收到这个信号默认的处理动作是:Term。
2.4.1 闹钟的返回值问题
我想看到的现象是收到闹钟前,进程会疯狂打印cnt计数器:
效果:
- 计数器才加了1万多次
为了对比为什么CPU计算速度这么快还是只打印1万多,证明是收到了闹钟信号:
一万多次肯定对于当前的CPU还是太少了,我们纯在内存当中做++:
真实情况下是把一个整数加到4亿多次:
至于有没有回绕呢?应该是没有的。
为什么会有这么大的数量级上的差别的呢?
输出的本质是IO,IO比较慢,这个IO是要经过网络的,要访问外设。
4亿多次是因为没有访问外设,直接访问了内存,内存级别的操作。
这样我们对CPU访问外设速度非常慢有了一个量化的认识。
我们验证了闹钟本身的一些操作。
如果我们设置一个20秒的闹钟,在第五秒的时候就把闹钟提前唤醒了,这种闹钟给一个进程只能设置一个,已经设置了,过了一段时间后悔了,要重设闹钟,下一次返回值就是返回上一个闹钟的剩余时间。
验证一下:
如果后悔了,设置闹钟为0秒:
就是返回上一个闹钟的剩余时间,0就是取消闹钟。
如下图,我们先设置alarm(10);,再设置成alarm(0);之后,因为第一个闹钟是10秒,使用返回了10 - 0 = 10秒。
我们把闹钟取消了,收不到闹钟,就会死循环:
我们改一下代码:
再过n个2秒我们就再也收不到闹钟了。
这就说明,alarm是一个一次性闹钟,而且这个闹钟只对这个进程只会有同一个闹钟(从头到尾调用alarm就一个闹钟)。
我们可能要对闹钟进行重复设置,时间得卡好!
- 下面这样写是不行的
当我调用下一个的时候闹钟就收不到闹钟了——上一个闹钟根本没有响!
重复设置一定要保证上一个闹钟已经被触发了。
一定要写在handlersig函数里:
此时我们就可以每隔2秒使用一次闹钟:
这就是闹钟的返回值问题。
2.4.2 闹钟的应用场景
闹钟功能具有延时触发的能力。
Windows中的关机程序:
shutdown-t10 -s(带选项) 实现 延迟关机 的功能。
其实严格意义上这个工作不是闹钟完成的,而是定时器完成的。
有点类似于“看门狗”——
- 使用 alarm 实现看门狗(B进程)
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<signal.h>#include<sys/shm.h>#include<sys/ipc.h>#defineMAX_COUNT100#defineSHM_KEY0x1234int*counter;// 共享内存指针voidwatchdog_handler(int signum){// 每次闹钟触发,计数器减1(*counter)--;printf("watchdog: counter = %d\n",*counter);if(*counter <=0){printf("watchdog: no feed, shutting down...\n");// 执行关机命令,如 system("shutdown -h now");exit(0);}// 重新设置1秒后的闹钟alarm(1);}intmain(){// 创建/获取共享内存int shmid =shmget(SHM_KEY,sizeof(int), IPC_CREAT |0666);if(shmid <0){perror("shmget");exit(1);} counter =(int*)shmat(shmid,NULL,0);*counter = MAX_COUNT;// 初始值// 注册信号处理函数signal(SIGALRM, watchdog_handler);// 启动第一个1秒闹钟alarm(1);// 进入无限循环,等待信号while(1){pause();// 等待闹钟信号触发}return0;}- A进程喂狗
A进程只需要通过共享内存访问计数器,并定期重置:
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/shm.h>#defineMAX_COUNT100#defineSHM_KEY0x1234int*counter;intmain(){// 获取共享内存int shmid =shmget(SHM_KEY,sizeof(int),0666);if(shmid <0){perror("shmget");exit(1);} counter =(int*)shmat(shmid,NULL,0);while(1){// 模拟正常工作printf("working...\n");sleep(80);// 每隔80秒喂狗一次(小于100秒即可)// 喂狗:重置计数器*counter = MAX_COUNT;printf("feed watchdog, counter reset to %d\n",*counter);}return0;}2.4.3 理解闹钟
理解闹钟,看看操作系统内同时存在多种闹钟(定时器)?操作系统要不要管理?怎么管理?先描述,再组织。
我们是先描述了:
怎么再组织呢?
- 如果未来5秒的闹钟没有响,那么后面的15秒的50秒的、150秒的一定没响。
只要关注未来超时时间最近的闹钟即可:
我们可以用什么数据结构来管理?
OS给目标进程发送 SIGALARM。
未来自己使用定时器应该会使用堆结构,这就是为了方便理解。
堆结构有缺陷,不能遍历,不能很好地支持取消。
- 闹钟,是单独硬件来计时吗?如果是CPU来计时的话,它不得很忙,一边处理进程,还一边计时。
问题1:闹钟是软件实现的!
问题2:闹钟计时取决于操作系统是如何运行的,操作系统也是个软件,谁运行操作系统?原因是,键盘可以产生中断,操作系统内部也存在一种硬件单元,晶振,也会触发中断,中断向量表,操作系统是基于中断的一种集合。
一般触发时钟中断的硬件周期是固定的,比如每隔一纳秒,因此在OS内部就可以定义一个全局变量记录中断次数,如果是100,等于说从开机到现在已经过了100纳秒了,次数 = 时间。时钟中断,token中断,操作系统能够算出来从开机到现在过了多少秒,5秒会变成5^9次!如果次数超过了就是超时。计算机里把时间转化成次数,计时不是由CPU计时的,由外部晶振的振动周期决定的。中断越强,CPU响应能力越强。
操作系统并不连续,而是一卡一卡的。
- 除0死循环,标志位没清,再次上下文时,要先检查
core dumped标志位,才运行吗
CPU已经识别出来了,也会走中断,走中断也会走中断向量表,也属于异常。
只要core dump一次就可以了。
自定义捕捉了就没有core dump了,没有走自定义捕捉就没有走系统那一套,就没有core dump了。
结尾
uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!
结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主“一键四连”哦!
往期回顾:
【Linux进程间通信:共享内存】为什么共享内存的 key 值由用户设置
🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡૮₍ ˶ ˊ ᴥ ˋ˶₎ა