在 Ubuntu(以及所有 Linux)里,僵尸进程(zombie, Z 状态)不能直接被 kill 掉,因为它们已经“死了”,只是父进程还没回收它们的资源。
唯一正确的清理方式是:让它们的父进程去回收,或者让父进程也退出。
下面按「排查 → 处理 → 预防」给你一套可批量操作的方法。
ps aux | awk '$8=="Z"'
或:
ps -eo pid,ppid,stat,cmd | grep Z
典型特征:
STAT 为 Z<defunct>ps -eo pid,ppid,stat,cmd | grep Z
示例输出:
12345 1100 Z [python] <defunct>
说明:
僵尸进程只能由父进程回收,所以:
kill -TERM 父进程PID
如果父进程不响应:
kill -9 父进程PID
父进程退出后,僵尸会被
init/systemd接管并自动清理。
✅ 这是唯一真正“清理”僵尸的方法
⚠️ 生产环境一定要确认父进程是谁
ps -eo ppid,stat | awk '$2=="Z" {print $1}' | sort -u
然后逐个或批量处理:
for ppid in $(ps -eo ppid,stat | awk '$2=="Z" {print $1}' | sort -u); do
echo "Killing parent $ppid"
kill -9 $ppid
done
docker ps
docker restart 容器名
或:
docker stop 容器名 && docker rm 容器名
通常是:
wait() 子进程os.fork() 但没回收✅ 修复方式:
signal.signal(SIGCHLD, SIG_IGN) 或 os.waitpidRuntime.exec() 滥用| ❌ 错误做法 | 原因 |
|---|---|
kill -9 僵尸PID |
僵尸已经死了,kill 无效 |
killall -9 defunct |
没用 |
kill -9 1 |
会直接关机 |
kill -STOP 父进程
kill -CONT 父进程
有时能触发回收,但不稳定,不建议生产使用。
wait() 子进程SIGCHLDKillMode=process
避免子进程成为孤儿
僵尸进程杀不掉,只能杀父进程或修代码。
如果你愿意,可以把下面信息贴出来,我可以帮你精确判断:
ps -eo pid,ppid,stat,cmd | grep Z
或者告诉我: