在 Ubuntu(以及一般 Linux 系统)里,僵尸进程(zombie / defunct)本质上是“已经结束但父进程还没回收”的进程。它不占用 CPU、内存,只占用一点进程表项;但如果大量积累,可能导致无法创建新进程。
下面从原理 → 排查 → 避免 → 处理四个方面说明。
exit)wait() / waitpid()Z(zombie)状态init/systemd 回收✅ 僵尸进程无法被 kill 强制杀掉,只能由父进程回收。
ps -ef | grep defunct
# 或
ps -l
状态为 Z 的就是僵尸进程。
在 C / Python / Shell 中:
signal(SIGCHLD, SIG_IGN); // 忽略子进程退出信号
或:
wait(NULL);
import signal
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
或:
os.waitpid(-1, 0)
避免无谓后台:
command & wait
systemd 管理服务(推荐)写 .service 文件,由 systemd 管理子进程生命周期:
[Service]
ExecStart=/opt/myapp
Restart=on-failure
✅ systemd 会自动回收子进程
常见问题:
✅ 解决:
nohup / setsid 小心nohup xxx &
如果父 shell 不退出,可能产生僵尸
✅ 更好方式:
setsid xxx &
ps -o ppid= -p <僵尸PID>
kill -9 <父进程PID>
父进程死后,僵尸会被 systemd 回收
systemctl restart 服务名
kill -9 僵尸PID # 没用
watch -n 5 "ps aux | awk '$8 ~ /Z/ {print}'"
或 Zabbix / Prometheus 监控 proc.stat.zombies
僵尸进程防不住,只能靠“父进程回收 + systemd 管理 + 不滥用后台进程”
如果你愿意,可以:
我可以帮你针对性避免僵尸进程。