在 CentOS(以及所有 Linux 系统)中,**僵尸进程(Zombie Process)**产生的根本原因是:子进程已经结束,但父进程没有正确处理(回收)它的退出状态。
下面从原理、常见原因、示例和解决方法几个方面说明。
在 Linux 中:
wait() / waitpid() 读取子进程状态僵尸进程已经不占用 CPU 和内存,只占用一个 PID 和进程表项
最常见原因,比如:
pid_t pid = fork();
if (pid == 0) {
// 子进程
exit(0);
} else {
// 父进程什么都不做
while (1) sleep(1);
}
子进程退出 → 父进程不回收 → 僵尸进程
有些程序错误地忽略了子进程结束信号:
signal(SIGCHLD, SIG_IGN);
或:
signal(SIGCHLD, SIG_DFL);
导致系统不会自动回收子进程。
✅ 正确做法:
signal(SIGCHLD, SIG_DFL); // 或显式 wait
例如:
即使收到 SIGCHLD,也没执行 wait()
如果父进程退出:
init(PID 1)接管systemdsystemd 会自动 wait() 子进程✅ 所以父进程退出通常不会产生长期僵尸
⚠️ 但如果 PID 1 异常(极少见),僵尸会一直存在
常见于:
ps aux | grep ' Z'
或:
top
看到:
Tasks: 120 total, 1 zombie
signal(SIGCHLD, SIG_DFL);
pid_t pid = fork();
if (pid == 0) {
exit(0);
} else {
wait(NULL);
}
或使用 sigaction:
struct sigaction sa;
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
CentOS 7+ 推荐:
systemd 启动服务无法直接 kill 僵尸进程
正确方式:
kill -9 父进程PID
父进程死后:
systemd / init 接管CentOS 产生僵尸进程,是因为子进程退出了,但父进程没有调用 wait() 回收它。
如果你有具体的 CentOS 版本 / 程序 / 日志 / 代码,我可以帮你精确定位原因。