在 CentOS(以及其它 Linux 发行版)中,**僵尸进程(Zombie / defunct)**的产生原因本质上只有一个:
子进程已经结束,但父进程没有调用
wait()/waitpid()来回收子进程的状态。
下面从“哪些操作/场景会引发僵尸进程”的角度说明。
僵尸进程出现的前提:
exit() 或被信号杀掉)此时子进程就变成了僵尸进程(状态为 Z)。
SIGCHLD 信号signal(SIGCHLD, SIG_IGN);
SIGCHLD✅ 正确做法:
signal(SIGCHLD, SIG_DFL);
或在 SIGCHLD 中调用 waitpid()
SIGCHLDfork() 后:
wait()SIGCHLD典型场景:
accept → fork → 退出)例如:
while (1) {
// 只处理业务,不回收子进程
}
或:
sleep()read()➡ 子进程退出后无人回收
command &
wait⚠ 长时间脚本更易出现
system() / popen() 不当system() 内部依赖 wait()SIGCHLDsystem() 可能失败并留下僵尸例如:
常见于:
在 CentOS 中:
ps -ef | grep defunct
或:
top
# 看 Tasks: zombie 数量
ps -o pid,ppid,stat,cmd
状态为 Z 即为僵尸。
❌ 不能直接 kill
kill -9 <zombie_pid> # 无效
✅ 解决办法:
kill -9 <parent_pid>
CentOS 中,僵尸进程不是“系统问题”,而是“父进程写错了”。
只要父进程:
SIGCHLDwait/waitpidfork + exec + exit 的清晰模型就不会产生僵尸进程。
如果你愿意,我可以:
ps 输出帮你定位父进程