僵尸进程与 fork 失败:从进程表定位父进程责任

解释僵尸进程为何出现,如何定位未回收子进程的父进程,以及 fork 失败时应检查的系统限制。

文章目录 · 4 节

僵尸进程已经结束执行,只保留退出状态等待父进程回收。少量短暂僵尸不一定有害,但持续累积会占用 PID,并最终导致 fork: Resource temporarily unavailable

找出僵尸及其父进程

ps -eo stat,pid,ppid,etimes,comm | awk '$1 ~ /^Z/'
pstree -ap $PPID
cat /proc/$PPID/status | grep -E 'Name|Threads|Sig'

僵尸本身无法被 kill -9 清除。应修复或重启没有调用 wait() 的父进程;父进程退出后,子进程会被 init 或 subreaper 接管并回收。

排查 fork 失败

ulimit -u
cat /proc/sys/kernel/pid_max
ps -eLf | wc -l
systemctl show "$SERVICE" -p TasksCurrent -p TasksMax

除了 PID 用尽,还要检查用户进程限制、systemd TasksMax、容器 PID cgroup 以及内存不足。线程也会计入任务数量。

处理边界

  • 先确认父进程和业务影响,再安排滚动重启
  • 不通过循环发送信号制造更大进程风暴
  • 容器入口进程应具备信号转发和子进程回收能力
  • 为 worker 数量、PID 使用率和僵尸数量建立监控

收尾清单

修复后验证僵尸数量不再增长,并通过异常退出、超时和重载场景测试父进程的回收逻辑。