人人都会AI编程

kill、killall:进程信号发送与终止

更新时间:2026-07-12

在 Linux 中,终止或控制一个进程并不是直接“杀死”它,而是通过向目标进程发送信号(signal)来实现。信号是内核提供的一种进程间异步通知机制,用来告诉进程“发生了某件事”,比如用户按下了 Ctrl+C、子进程结束、定时器到期等。killkillall 是用于手动发送信号的两个最常用命令,它们的名字容易让人误以为只能用来终止进程,实际上功能要丰富得多。

1. kill:向指定进程 ID 发送信号

最基本的 kill 命令格式是 kill [信号] PID,例如:

kill 1234          # 默认发送 TERM(终止)信号
kill -9 1234       # 发送 KILL 信号,强制杀死
kill -HUP 1234     # 发送 HUP 信号,常用于重新加载配置

这里的 PID 是进程的唯一标识,可以用 pstoppidof 等命令获取。

常用信号及其含义:

  • TERM (15):默认信号,请求进程正常退出。程序可以捕获这个信号,在退出前执行清理工作(如关闭文件、保存状态)。
  • KILL (9):强制杀死进程,内核会立即终止它,程序无法捕获或忽略。只有在进程卡死、不响应 TERM 时才应使用,因为它让程序来不及善后。
  • HUP (1):最初设计是终端挂断信号,现在最常用于让守护进程重新读取配置文件而无需重启。
  • INT (2):相当于在终端按下 Ctrl+C,通常中断前台进程。
  • STOP (19)CONT (18):暂停和恢复进程,可用于任务控制。

信号可以用数字或名字指定,例如 kill -15 等同于 kill -TERMkill -l 可以列出所有信号。

2. killall:按进程名发送信号

killall 不需要知道 PID,直接按程序的名字发送信号。例如:

killall nginx         # 向所有名为 nginx 的进程发送 TERM
killall -9 java       # 强制杀死所有 java 进程(谨慎使用)
killall -HUP sshd     # 让 sshd 重新加载配置

它的语法与 kill 一致,只是参数从 PID 换成了进程名。需要注意:

  • 默认会匹配所有同名的进程实例,比如 killall chrome 会杀掉所有正在运行的 chrome 窗口。
  • 可以使用 -u 指定用户,killall -u zhangsan firefox 仅终止属于 zhangsan 的 firefox 进程。
  • 对于精确匹配,killall 要求完整的进程名(如 nginx 而非 ng),但有些实现支持 -e--exact 选项。
  • 在 Solaris 等系统上 killall 行为不同(会杀掉所有进程),但 Linux 版本是安全的。

3. 何时使用 kill,何时使用 killall

  • kill:当你知道具体 PID 时(比如从日志中抓取、通过 pidof 查询),或者需要精确操作单个进程时。
  • killall:当你只知道进程名字但懒得查找 PID 时,或者想一次性向多个同名进程发送信号时(比如批量重启所有 worker 进程)。

4. 实用建议

  • 尽可能先使用 TERM(默认)或 HUP,给进程一个妥善退出的机会,避免数据丢失或留下锁文件。
  • 只有在进程已经无响应、TERM 无效时才使用 KILL。发出 KILL 后进程立即消失,不会有任何提示。
  • 在杀死前可以用 pgrep 进程名pidof 进程名 预览将被影响的 PID,避免误杀。
  • 如果进程是 systemd 等服务管理器管理的,优先使用 systemctl stop 服务名,因为这些管理器会正确地发送信号并跟踪状态。

5. 综合示例

假设 Nginx 服务日志不正常,需要重新加载配置,而某个僵死的 Java 进程必须强制终止:

# 平滑重启 nginx(重新打开日志文件)
killall -USR1 nginx
# 强制终止一个卡死的 java 进程(假设 PID 为 9876)
kill -9 9876
# 让 crond 服务重新读取 crontab 文件
kill -HUP $(pidof crond)

这些命令简单直接,但功能强大,是日常管理和排错中不可或缺的基础技能。