在 CentOS(以及所有 Linux 系统)中,僵尸进程(Zombie / defunct 进程)本质上不是“系统自己产生的”,而是由进程管理机制决定的正常但未被清理的状态。下面从“来源”和“原因”两个层面说明。
僵尸进程的来源只有一种核心情况:
一个子进程结束了,但它的父进程还没有调用
wait()/waitpid()来回收它
这时,子进程:
这就是僵尸进程。
pid_t pid = fork();
if (pid == 0) {
// 子进程
exit(0);
}
// 父进程什么都不做,也不 wait
while(1) pause();
结果:子进程变成 zombie。
很多程序错误地认为:
signal(SIGCHLD, SIG_IGN);
可以自动回收子进程(在一些 UNIX 上可以,但在 Linux/CentOS 上不可靠)
导致子进程无人回收 → 僵尸。
典型例子:
&例如:
./worker &
# 父 shell 很快退出,但 worker 被 init 接管前可能短暂僵尸
SIGSTOP结果:子进程退出后,没人回收。
例如:
如果它们 fork() 了子进程但不 wait():
| 情况 | 结果 |
|---|---|
父进程正常 wait() |
僵尸消失 |
| 父进程退出 | 僵尸被 init(PID 1)接管并回收 |
| 父进程一直活着 | 僵尸永久存在 |
⚠️ CentOS 7+ 的 PID 1 是 systemd,仍然会回收孤儿进程
ps -ef | grep defunct
或
top
# 看 Tasks: xx zombie
ps -o pid,ppid,stat,cmd -p <僵尸PID>
看 PPID。
✅ 僵尸进程来自:
❌ 不是来自:
如果你愿意,可以:
ps 输出我可以帮你精准定位僵尸来源并给出解决方式。