kill 默认不是"杀死":进程信号与 nice 优先级实战
kill -9 是很多人的肌肉记忆——进程不听话,直接 -9 送走。但 kill 这个命令名其实起得有误导性:它默认发的信号根本不是”杀死”,而是”请求退出”。这两者的区别,决定了进程退出前有没有机会保存数据、释放资源。
这是 Linux 命令系列的一篇,承接 Linux 常见命令与工具地图;服务器排查那篇 讲了用 ps/top 找进程,这篇讲找到之后怎么正确地”管”它。
信号:内核给进程递的通知条
信号(signal)是内核发给进程的一种异步通知。大部分信号进程可以选择怎么响应——捕获它执行自定义逻辑、忽略它、或者按默认行为处理;只有极少数信号(比如 SIGKILL)是强制的,进程没有任何选择余地。
1 | kill -l |
kill 命令的作用就是给指定 PID 的进程发信号——发什么信号由参数决定,不指定就发默认的。
SIGTERM(15):kill 的默认信号,请求优雅退出
1 | kill 12345 |
绝大多数正经写的服务都注册了 SIGTERM 处理逻辑(Go 里的 signal.Notify、容器里的优雅停机钩子都是响应它),收到后会体面地收尾。这也是 systemctl stop、docker stop 停服务时先发的信号。
SIGKILL(9):最后手段,不是首选
1 | kill -9 12345 |
-9 的问题不在”杀不死”,恰恰在”杀得太死”:进程的清理逻辑一行都不会执行。数据库进程被 -9 可能留下损坏的数据文件,持锁的进程被 -9 可能让别的进程永远等锁。正确的顺序是:
1 | kill 12345 |
把 -9 当默认选项,等于放弃了所有进程善后的机会——它应该是 SIGTERM 无效之后的最后手段。
SIGHUP(1):重载配置的约定俗成
SIGHUP 历史上表示”终端挂断”(hangup,拨号上网时代的遗产),现在大量守护进程把它重新定义成”重新加载配置文件,但不重启”:
1 | kill -HUP $(cat /var/run/nginx.pid) |
不是所有程序都遵守这个约定,用之前查一下目标服务的文档;但见到 kill -HUP 时要知道,它的意图大概率是”重载配置”,不是杀进程。
pkill / pgrep:按名字找和杀,跳过查 PID
pgrep 按进程名查 PID,pkill 按进程名直接发信号——省掉 ps aux | grep xxx 再手动复制 PID 的三步操作:
1 | pgrep -l nginx |
pkill -f 是双刃剑:模式写宽了会把不相干的进程一起杀掉。安全的习惯是先跑一遍同参数的 pgrep -fl,看清楚列表再动手。
nice / renice:CPU 调度优先级
nice 值决定进程在 CPU 竞争中的优先级,范围 -20 到 19——数值越低优先级越高,这个方向和直觉相反:可以理解成”nice 值越高,进程越’客气’,越愿意把 CPU 让给别人”。普通用户只能调高 nice 值(降低优先级),设负值需要 root。
1 | nice -n 19 tar -czf backup.tar.gz /data |
常用命令速查表
| 命令/信号 | 作用 |
|---|---|
kill PID |
发默认信号 SIGTERM(15),请求优雅退出 |
kill -9 PID |
SIGKILL,内核强制终结,无清理机会,最后手段 |
kill -HUP PID |
多数守护进程约定为”重载配置不重启” |
kill -0 PID |
不发实际信号,只检测进程是否存在 |
kill -l |
列出全部信号 |
pgrep -l 名字 |
按进程名查 PID |
pkill 名字 |
按进程名发 SIGTERM |
pkill -f 模式 |
按完整命令行匹配,先用 pgrep -fl 确认再杀 |
nice -n N 命令 |
以指定优先级启动,-20 最高、19 最低,越低越优先 |
renice -n N -p PID |
调整运行中进程的优先级,负值需要 root |
写到这里
kill 家族的正确打开方式:默认 SIGTERM 给进程体面退出的机会,几秒后还赖着不走再 -9;重载配置认准 SIGHUP;批量操作用 pkill 但先 pgrep 确认目标。至于 nice,记住”值越低越优先”这个反直觉设定,剩下的就是两条命令的事。










