在 Ubuntu(以及所有 Linux 系统)中,僵尸进程(Zombie Process)本质上是已经结束但还没有被父进程回收的进程。它们不占用 CPU 或内存,但会占用进程号(PID)。
✅ 重点结论:
僵尸进程不能直接被 kill 掉,只能通过 让它的父进程回收它 或 让父进程退出 来清除。
僵尸进程状态为 Z(Zombie):
ps aux | grep 'Z'
或:
ps -eo pid,ppid,stat,cmd | grep 'Z'
示例:
PID PPID STAT CMD
1234 1000 Z [myapp] <defunct>
STAT=Z → 僵尸<defunct> → 已死但未回收常见原因:
wait() / waitpid()找到僵尸进程的 父进程 PPID:
ps -eo pid,ppid,stat,cmd | grep Z
假设:
PID PPID
1234 1000
然后:
kill -SIGCHLD 1000
如果父进程正常,它会回收子进程。
如果父进程不处理 SIGCHLD:
kill 1000
或强制:
kill -9 1000
一旦父进程退出:
init(或 systemd,PID 1)接管init 会自动回收✅ 僵尸进程随后消失
如果是服务产生的僵尸:
systemctl restart your-service
例如:
systemctl restart nginx
systemctl restart php-fpm
kill -9 僵尸PID
❌ 无效,因为进程已经死了,只是残留 PCB。
wait()wait(NULL);
或:
waitpid(pid, NULL, 0);
signal(SIGCHLD, SIG_IGN);
适用于不关心子进程退出状态的情况
父 -> 子 -> 孙
子立刻退出
孙被 init 接管
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/'
| 场景 | 解决方案 |
|---|---|
| 单个僵尸 | kill 父进程 |
| 服务产生僵尸 | systemctl restart |
| 父进程卡死 | kill -9 父进程 |
| 防止僵尸 | wait / SIGCHLD |
| kill 僵尸进程 | ❌ 无效 |
如果你愿意,可以把你的 ps -ef 输出 或 具体服务名 发出来,我可以帮你精确判断该杀哪个进程。