在 **CentOS(以及所有 Linux 系统)**上,**僵尸进程(Zombie Process)**的产生原因本质上和操作系统进程管理机制有关,并不是 CentOS 独有的问题。下面从原理、常见原因、示例和解决方法几个方面说明。
僵尸进程是:
已经结束运行,但其进程描述符(task_struct)仍留在进程表中,没有被父进程回收的子进程
它的状态是:
STAT = Z
例如:
ps aux | grep Z
输出中常见:
user 12345 0.0 0.0 0 0 ? Z 10:00 0:00 [test] <defunct>
子进程退出后,父进程没有调用 wait() / waitpid() 回收子进程状态
流程如下:
SIGCHLDwait() 获取子进程退出状态这是最常见原因,例如:
wait()SIGCHLD示例(C 语言):
pid_t pid = fork();
if (pid == 0) {
exit(0); // 子进程退出
}
// 父进程没有 wait()
while (1) {
sleep(1);
}
结果:子进程变成僵尸。
例如:
signal(SIGCHLD, SIG_IGN);
在某些历史实现中,这会导致子进程无法被回收(现代 Linux 通常不会,但仍是隐患)。
init(或 systemd)接管wait(),也可能短暂出现僵尸fork(),只有一个线程被复制wait() 逻辑复杂,容易遗漏✅ 僵尸进程不占用 CPU、内存、文件描述符
✅ 只占用一个进程号(PID)和进程表项
❌ 无法被 kill 掉
kill -9 zombie_pid # 无效
因为:
僵尸进程已经死了,只是“尸体”还没被父进程收尸
wait()waitpid(-1, NULL, 0);
或处理 SIGCHLD:
void handler(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0);
}
kill -9 父进程PID
init / systemd 接管wait()这是生产环境中最常用的临时解决方案
systemd 管理服务fork()wait()仍然会产生僵尸
ps -eo pid,ppid,stat,cmd | grep Z
重点关注:
PPID(父进程是谁)STAT=ZCentOS 出现僵尸进程,不是系统问题,而是程序问题:子进程退出了,父进程没回收。
如果你愿意,可以把:
ps -ef贴出来,我可以帮你具体分析是哪一类问题。