linux 的信号系统其实是一个非常重要的概念, 进程间通信的常用方法之一;
不过长期以来, 我们对 linux 信号的直观认识, 只有 kill (SIGTERM), ctrl + c (SIGINT) 和 kill -9 等进程终止信号; 而 linux 的信号系统中存在 64 种各司其职的信号, 适用于各种各样的场景; 很多信号在实际工作中有着妙用;
本文正是想对 linux 世界中林林总总的 signals 作一次梳理, 总结一些日常工作中频繁使用以及不太接触但十分有用的信号;
linux signals 总览
linux siginal 可分为如下几大类:
- 系统错误信号
- 进程终止信号
- 作业控制信号
- AIO 信号
- 定时器信号
- 操作错误信号
- 其他信号
linux signals 的产生源一般分为三类: 硬件方式(除数为 0, 内存非法访问等), IO 方式(键盘事件), 以及软件方式: kill 命令, alarm 定时器等;
其中我们最熟悉的莫不过 kill 命令了, 详情请见: kill 命令族及其选项;
使用 kill -l 查看所有信号分布:
1 | > kill -l |
各类别信号整理
进程终止信号
进程终止信号是我们日常操作中最常用的一类信号;
进程终止信号共有五个, 其中除了 SIGKILL 之外, 其他信号都是 可阻塞, 可忽略, 可处理的;
1 | # terminate, kill 不加任何选项的默认信号, 默认处理是终止进程; |
另外一篇详细梳理与 SIGHUP 相关知识点的链接: SIGHUP 相关全梳理;
该文章主要涉及 SIGHUP 信号发生的条件, 传导, 与 SIGHUP 相关的 nohup, &, shopt huponexit, disown 等概念, 并包括一些 SIGHUP 的自定义应用;
任务控制信号
其他信号
其他信号是指未在上述分类中的一些小众信号, 这些信号本身并未有太多关联, 不能用一个类别去统一描述它们;
(1) 用户自定义信号: SIGUSR1 / SIGUSR2
这两个信号, linux 保证系统自身不会向进程发送, 完全由使用者自己定义该信号的语义以及处理逻辑;
SIGUSR1 与 SIGUSR2, 在系统层面完全没有区别, 如果可以, linux 其实能再定义一个 SIGUSR3; 所以用户自定义信号的预留数量, 本身是一个模糊的界定;
以下是 SIGUSR1 / SIGUSR2 的具体使用场景:
1 | # 通知 nginx 关闭当前句柄, 重新打开日志文件, 用于 logrotate 切割日志 |
(2) SIGWINCH (winch 译作: 吊车, 摇柄), 默认处理是忽略该信号;
以下是 SIGWINCH 的具体使用场景:
1 | # 通知 nginx worker process 不再接受新 request, 并从容关闭 |
当然, 通知 worker process 不再接受新请求, nginx 并不需要使用者直接在 linux signals 层面直接处理, nginx 本身提供了平滑重启命令 sbin/nginx -c conf/nginx.conf -s reload
, SIGWINCH 信号的发送封装在了该命令里;
关于 nginx 与 linux signals 的关系, 在本站另一篇文章中有详细介绍: nginx signals 处理;