Linux 信号
什么是 Linux 信号?是一种进程通信机制。就像十字路口的信号灯一样,当不同的车辆(类似进程)收到信号之后,会按照信号预定的含义行事,红灯停绿灯行。 然而,也有车辆违章行事或者事出紧急。进程在收到信号之后,也可以改变默认的行为,做自己想做的事情。
什么是信号
在 《Linux processes and signals》一文中有如下描述:
信号一种通知,由操作系统或一些应用程序将一条消息发送给我们的程序。信号是一种单项的异步通知机制。一个型号可能从内核发送给进程,可能从一个进程发 送给另一个进程,或者从一个进程发送给他自己。信号通常用来通知进程发生了一些事情,比如说段错误,或者用户按下了 Ctrl-C 组合键。
信号的分类
Linux 信号可以分为下面两种类型:
Maskable: 信号默认的行为可以被用户更改或者忽略。Non-Maskable: 信号不能被用户更改或忽略,比如说硬件发生了不能回复的错误。
常用的信号
Linux 内核定义了大概 30 个信号。每一个信号都有一个唯一标识的数字,从 1 到 31。信号没有任何的参数,他们的名字都解释了他们的作用。比如说, SIGKILL 这个信号的编码是 9,他告诉指定的进程有人在尝试结束他。
你可以通过 kill -l 命令来查看自己的 Linux 发行版支持的所有的信号:
我们并没有必要记住所有的信号量,但是对某些常用的信号量应该知悉,列举如下表:
信号量 | 含义 |
|---|---|
SIGCHLD-17 | 由子进程发送给父进程,告知子进程已经结束 |
SIGQUIT-3 | 表示终端推出 |
SIGTERM-15 | 终止进程,由进程决定什么时候关闭,优雅的关闭 |
SIGKILL-9 | 终止进程的运行,不会等待 |
SIGHUP | 迫使进程重新读取配置文件,挂起检测 |
SIGUSR1 | 用户自定义的信号量1 |
SIGUSR2 | 用户自定义的信号量2 |
SIGWINCH | 表示窗口(Window)发生改变(Change) |
SIGINT | 和 SIGKILL 信号的区别在于其不能被捕获和忽略,使用 |
Shell 程序信号处理
在 Shell 中,使用 kill 命令来向进程发送信号。如果不指定信号量 kill <pid>, 默认发送的是 SIGTERM 信号,允许进程自身去决定结束的时机 ,一般进程会利用接受到信号到结束进程之间的时间来处理数据,完成请求等操作,是的进程可以优雅的结束。
下面这个程序,接受并处理了 SIGINT 信号:
执行上面这个程序,按下 Ctrl+C 会向这个 Shell 程序的进程发送一个 SIGINT 的信号,屏蔽了默认的该信号的处理程序,即不会退出该程序。如果需 要推出该程序,按下 Ctrl+Z 中断程序的执行,然后使用 kill -9 向该进程发送终止信号。
参考资料
《Linux Shell 脚本攻略》第三版—— 第十章 管理重任
慕课网《新版Nginx1.17体系深度精讲 给开发和运维的刚需课程》Linux的信号量管理