在 Ubuntu(以及所有 Linux 系统)中,**僵尸进程(Zombie Process)**的出现原因本质只有一个:子进程已经结束,但父进程还没有“收尸”(没有调用 wait() / waitpid() 来读取子进程的退出状态)。
下面从原理、常见原因、示例和如何处理几个方面说明。
fork() 创建子进程wait() / waitpid() 获取这些信息僵尸进程已经不占用 CPU 和内存,只占用一个 PID 和进程表项。
wait()示例(C):
if (fork() == 0) {
exit(0); // 子进程退出
}
while (1) {
// 父进程没 wait()
}
结果:
ps aux | grep Z
例如:
sleep()SIGCHLDSIGCHLDwait()
就会造成僵尸正确做法:
signal(SIGCHLD, SIG_IGN); // 自动回收(不推荐滥用)
或
void handler(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0);
}
常见于:
& 启动子进程但不等待正常情况下:
init / systemd(PID 1)收养wait(),僵尸会消失但如果:
systemd 管理的异常服务就可能看到持续僵尸。
✅ 一般危害很小
❌ 但大量僵尸会:
ps aux | grep Z
或:
top
# 看_tasks_ 里的 zombie 数量
查看父进程:
ps -eo pid,ppid,stat,comm | grep Z
wait()SIGCHLD 信号处理system() / popen() 时注意回收kill -9 父进程PID
❗ 不能直接 kill 僵尸进程
Ubuntu 的僵尸进程不是“死不掉”,而是“父进程没来领尸”。
如果你愿意,可以把:
ps 输出发出来,我可以帮你具体分析为什么会出现僵尸。