🔝🔝🔝
本文重点:
- 掌握Linux信号的基本概念。
- 掌握信号产⽣的⼀般⽅式。
2. 信号的基本概念
2.1什么是Linux信号?
信号本质是一种通知机制,用户或操作系统可通过发送信号通知进程某些事件已发生,让进程后续进行处理。
信号的产生,相对于进程的进行,是异步的。
我们可以通过生活中的信号进行类比理解。
生活中的信号,是闹钟,将人从睡眠状态唤醒;
是快递到站通知,通知你去快递站取快递;
是敲门声,通知你开门…
一言概之,信号中断人正在做的事情。
什么是同步?什么是异步?
同步:就像一群人排队依次通过安检,每个人都要等前面的人完成安检后才能前进,大家的行动是依次进行、相互等待的,这就是同步,在这个过程中每个环节是按顺序紧密相连的。
异步:比如你在网上下单买东西,下单后你不用一直等着商家立刻发货,你可以去做其他事情,商家会在合适的时候发货,你和商家的操作不是同时进行、相互等待的,这就是异步,各自的操作有一定的独立性和自主性。
换言之,信号产生后,并不需要立即处理,而是可以等一会儿在合适的时候进行处理。
基本结论:
1.进程在信号没有产生的时候,早已经知道信号如何处理了。因为进程中已经内置了对于信号的识别和处理方式。
2.信号的产生是随机的,收到信号时,此进程可能正在忙于其他事情。因此,信号的处理,不是立即处理,而是可以等一会儿在合适的时候进行处理。
3.既然信号不是立刻就处理的,那么一定存在某种结构来短暂保持收到的信号。
2.2查看信号列表
使用
kill -l
命令查看信号列表。
在 Linux 中,信号可分为普通信号(1 - 31 号)和实时信号(34 - 64 号),普通信号不支持排队,当多个相同的普通信号发送给一个进程时,进程可能只会处理一次。实时信号支持排队,意味着如果有多个相同的实时信号发送给一个进程,进程会按照信号发送的顺序依次处理每个信号,不会丢失。本文主要介绍普通信号。
对于信号的理解可以分为:信号的产生,保存以及处理。
而本篇文章讲解的则是信号的产生,信号的产生一共有四种方式:
- 终端按键产生信号。
- 使用系统调用产生信号。
- 调用系统命令kill。
- 硬件异常产生信号
3. 信号产生的方式概述
方式一:终端按键
例如使用CTRL+c
或CTRL_/
的方式产生信号
CTRL+c
产生的是2号信号,也就是SIGINT
信号
CTRL+/
产生3号信号,也就是SIGQUIT
。
使用man 7 singal
查看信号描述。
Term
代表终止这个进程,因此CTRL+c
可以终止进程。
注意信号SIGKILL
无法被自定义调用!(自定义调用将在下篇文章进行详细讲解)
前台进程和后台进程
有一个现象很值得关注,相同一条命令,使用
CTRL+C
可以终止进程,但如果在该命令后面加上&
后,这个进程就不能终止了。
想要解释这一现象,需要先了解前台进程和后台进程这两个概念。
前台进程
-
定义:
-
前台进程是在终端中与用户直接交互的进程。
-
它会占据终端的输入输出,用户输入的指令会直接被它接收并处理,处理结果也会实时显示在终端上。
-
只有当前台进程执行完毕或被暂停等操作后,用户才能在终端进行其他交互操作。
-
-
特点
-
在运行期间,终端被其独占,无法同时与其他进程交互。
-
在资源分配上,通常会优先获得系统的响应,以保证交互的流畅性。
-
后台进程
- 定义:
- 后台进程是在系统后台运行的进程。
- 它不与用户进行直接的交互,在启动后会在后台默默执行任务,不会占据终端的输入输出,用户可以在不影响其他操作的情况下让其在系统中持续运行。
- 特点
- 非交互性:在后台独立运行,不需要用户实时干预和操作。
- 终端无关:不依赖于终端,即使终端关闭,某些后台进程也可能继续运行。
- 稳定性要求高:通常用于执行一些需要长期稳定运行的任务,如系统服务等。
如何管理前后台进程
将前台进程放到后台:
使用 Ctrl+Z
暂停前台进程,然后使用 bg
命令将其放到后台继续运行。
例如:
sleep 50 # 启动一个前台进程
^Z # 暂停前台进程
bg # 将暂停的进程放到后台继续运行
将后台进程放到前台:
使用 fg
命令将后台进程放到前台。
例如:
sleep 100 & # 启动一个后台进程
jobs # 查看当前终端中的所有作业
fg %1 # 将作业编号为1的后台进程放到前台
查看当前的前后台进程:
使用 jobs
命令查看当前终端中的所有作业。
使用 ps
命令查看系统中的所有进程。
因此,命令加上
&
后,对应的进程成为了后台进程。而通过键盘发送信号只针对于前台进程,对后台进程无效。
方式二:系统调用
在函数中调用kill
,raise
,abort
等函数也能产生信号。
-
kill
是向指定进程发送指定的信号。
-
raise
是向自己发送指定的信号。
-
abort
是终止当前进程(发送6号信号)。
方式三:调用系统命令kill
kill -9 [pid]
方式四:硬件异常
例如除0错误,野指针都是由于硬件异常而产生的信号,从而导致进程被终止。
所有的信号都有它的来源,但最终全部都被操作系统识别,解释,并且发送给进程。
4. 信号的保存
上面说到,信号被进程接收到后不会立马处理,那么就要存在一个结构来保存信号,而这个结构就是位图。
信号有1~31号信号,那么只需要31个bit位即可保存完所有的信号,x号bit位中的0/1代表是否收到第x号信号,而这个位图结构是每个进程独有的,所以它很明显在进程的PCB中保存。
信号发送的本质:操作系统向目标进程发送信号,也就是操作系统直接修改PCB中指定的位图结构,修改完成后即为成功发送信号。