在 Ubuntu(以及其它 Linux 发行版)里,“僵尸进程(zombie / defunct)”本身是杀不掉的,这不是 bug,而是由 Linux 进程模型决定的。下面分层解释原因和正确处理方式。
僵尸进程不是还在运行的进程,而是:
exit()task_struct 中的最小信息(PID、退出码等),等父进程来“收尸”所以它:
kill -9 <pid> # 无效
因为 没有可执行代码可以杀。
kill -9 为什么没用kill -9 是发给“活进程”的信号,而僵尸进程:
僵尸进程不是进程的问题,是“父进程”的问题
僵尸存在的唯一目的:
让父进程通过
wait()/waitpid()获取子进程退出状态
如果父进程:
wait()子进程就会一直僵尸。
找到僵尸的父进程:
ps -l
# 或
ps -eo pid,ppid,stat,comm | grep Z
假设:
PID PPID STAT COMMAND
1234 567 Z bash
杀掉父进程:
kill -9 567
之后:
init / systemd(PID 1)接管wait()在父进程中正确处理子进程退出:
signal(SIGCHLD, SIG_IGN); // 自动回收
或:
waitpid(-1, NULL, WNOHANG);
或使用:
systemd 服务supervisorfork + exec + wait如果父进程是 PID 1 但仍有僵尸:
sudo systemctl daemon-reexec
或重启系统D 状态(不可中断睡眠)top 里看到 Z 但一直存在僵尸进程杀不掉,是因为它已经死了;你该杀的是“不收尸的父进程”。
如果你愿意,可以贴一下:
ps -eo pid,ppid,stat,comm | grep Z
我可以帮你具体看是哪个父进程在“赖着不回收”。