在 CentOS(以及一般 Linux 系统)上,僵尸进程(Zombie / defunct)本质上是子进程已经结束,但父进程还没有调用 wait() / waitpid() 回收其退出状态导致的。
预防僵尸进程的关键思路是:让父进程正确回收子进程,或让 init 接管孤儿进程。
下面按「原理 → 常见做法 → CentOS 实际建议」说明。
task_struct(含退出码)wait() 才能清除Z(zombie)➡️ 大量僵尸进程会导致 PID 耗尽,系统无法创建新进程
在 C / Python / Shell 中:
signal(SIGCHLD, SIG_IGN); // 忽略子进程退出信号(自动回收)
或
while (waitpid(-1, NULL, WNOHANG) > 0);
import signal
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
✅ 推荐:
SIGCHLD + waitpidsignal(SIGCHLD, SIG_IGN)(简单粗暴)常见问题程序:
while(1) 没 waitfork 后不回收✅ 建议:
systemd 管理systemd(CentOS 7/8/Stream 强烈推荐)systemd 会自动:
示例 service:
[Service]
Type=simple
ExecStart=/opt/app/run.sh
Restart=on-failure
✅ 不要手动 nohup & 长期跑程序
错误示例:
./child & # 父脚本不 wait
改进:
./child &
wait
或:
./child & disown
如果父进程崩溃:
PID 1(systemd / init)接管❌ 但如果父进程活着但不 wait → 僵尸
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/'
或
top
# 看 Tasks: x zombie
cgroup 限制⚠️ 僵尸进程无法直接 kill
解决方式:
kill -9 父进程PID
→ 子进程被 systemd 接管并回收
CentOS 预防僵尸进程 = 父进程正确 wait + 用 systemd 管理进程 + 避免长期不回收的子进程
如果你愿意,可以: