温馨提示×

ubuntu僵尸进程怎么来的

小樊
40
2026-10-24 19:11:18
栏目: 智能运维

在 Ubuntu(以及所有类 Unix 系统)里,**僵尸进程(Zombie Process)**的本质是:

子进程已经结束,但父进程还没有“收尸”(没有调用 wait() / waitpid() 获取子进程退出状态)

下面从「怎么来的」「为什么还在」「常见场景」三个角度说明。


一、僵尸进程是怎么产生的

简化流程:

  1. 父进程 fork() 创建一个子进程
  2. 子进程运行结束(正常退出或崩溃)
  3. 内核保留子进程的 退出状态、PID 等信息
  4. 父进程必须调用 wait() / waitpid() 来“回收”子进程
  5. 如果父进程一直不回收 → 子进程变成僵尸进程(Zombie)

在进程状态中表现为:

ps aux

状态为 Z(zombie)


二、为什么僵尸进程“杀不掉”

僵尸进程已经死了,它:

  • 不占用 CPU
  • 不占用内存(除了极小的 task_struct)
  • 不能被 kill -9 杀死

只能:

  • 让父进程回收
  • 或杀掉父进程,由 init / systemd 接管并回收

三、Ubuntu 中常见的僵尸进程来源

1️⃣ 程序写得不规范(最常见)

pid_t pid = fork();
if (pid == 0) {
    exit(0);   // 子进程退出
}
// 父进程忘了 wait()

→ 子进程变僵尸

✅ 正确做法:

wait(NULL);

或使用 signal(SIGCHLD, SIG_IGN)


2️⃣ 父进程卡死 / 阻塞

父进程:

  • 死循环
  • 阻塞在 I/O
  • 死锁

导致永远没机会 wait()


3️⃣ 服务程序 bug(常见于旧服务)

如:

  • 老版本 apache
  • 自定义 daemon
  • 脚本频繁 fork

4️⃣ 临时脚本 / shell 产生

例如:

sh -c 'sleep 100 &'

父 shell 退出后,子进程被 init 接管(一般没问题)

但如果父进程长期存在,就可能产生僵尸


四、怎么看僵尸进程

ps aux | grep Z

或:

top

看 Tasks: x total, y zombie


五、怎么处理僵尸进程(Ubuntu)

✅ 方法 1:杀掉父进程(最常用)

pstree -p | grep Z
kill -9 父进程PID

之后由 systemd(PID 1)回收


✅ 方法 2:修复程序(根本解决)

  • 加 wait()
  • 或用 sigaction(SIGCHLD)

❌ 错误做法

kill -9 僵尸PID

没用,僵尸已经死了


六、僵尸进程有危害吗?

少量僵尸:

  • 基本无害

大量僵尸:

  • 耗尽 PID(系统无法创建新进程)
  • 说明程序有重大 bug

如果你愿意,可以:

  • 贴 ps / pstree 输出
  • 或说明是 哪个程序产生僵尸

我可以帮你具体分析是哪种原因。

0 踩