Skip to content

Init 进程

Init 进程是 Linux 内核启动后拉起的第一个用户空间进程,PID 固定为 1。现代系统中它通常是 systemd。它的职责不是处理普通业务请求,而是启动系统、管理服务、收养孤儿进程,并在系统关闭时协调收尾。

PID 1 的位置

启动链路可以简化为:

  1. 固件加载引导程序。
  2. 引导程序加载内核。
  3. 内核初始化硬件、内存、调度器和根文件系统。
  4. 内核启动第一个用户空间进程,也就是 PID 1。
  5. PID 1 继续启动系统服务和登录环境。

如果 PID 1 出问题,影响的是整个系统级别的启动和服务管理。

Init 系统演进

类型特点现状
SysV Init按脚本和运行级别顺序启动老系统中常见
Upstart事件驱动,曾用于部分发行版现在较少见
systemdunit、依赖、并行启动、统一日志主流发行版默认

判断当前 PID 1:

bash
ps -p 1 -o pid,comm,args
cat /proc/1/comm

PID 1 的特殊职责

启动系统服务

PID 1 根据配置启动系统服务,例如网络、日志、登录、定时任务、业务服务等。使用 systemd 时,这些服务由 unit 管理。

收养孤儿进程

如果父进程退出,子进程还在运行,子进程会变成孤儿进程,被 PID 1 收养。PID 1 需要在这些子进程退出时回收状态。

处理系统关闭

关机、重启、切换运行目标时,PID 1 会协调停止服务、卸载文件系统、发送信号。

孤儿进程和僵尸进程

孤儿进程不是错误,它只是父进程退出后被 PID 1 接管。

僵尸进程是子进程已经退出,但父进程没有读取它的退出状态。僵尸本身不占用大量内存,但会占用 PID 表项。大量僵尸通常说明父进程没有正确处理子进程退出。

排查:

bash
ps -eo stat,ppid,pid,cmd | grep '^Z'
pstree -ap

处理重点是父进程,而不是僵尸进程本身。

启动问题排查

使用 systemd 时:

bash
systemd-analyze
systemd-analyze blame | head
systemd-analyze critical-chain
systemctl --failed
journalctl -b -p err

这些命令分别回答:

  • 启动总耗时是多少。
  • 哪些服务启动慢。
  • 关键路径卡在哪里。
  • 哪些服务失败。
  • 本次启动有哪些错误日志。

容器里的 PID 1

容器中也有 PID 1。很多问题来自把普通应用直接作为容器 PID 1:

  • 信号处理不完整,容器停止不优雅。
  • 子进程退出后无人回收,产生僵尸。
  • 没有服务管理和日志转发策略。

容器中应确保主进程能正确处理 SIGTERM,必要时使用轻量 init,例如 tini

不要随意操作 PID 1

不要随意向 PID 1 发送信号。对 PID 1 的错误操作可能导致系统关机、服务失控或容器退出。

需要管理服务时,优先使用:

bash
systemctl restart 服务名
systemctl reload 服务名
systemctl status 服务名

总结

Init 进程是系统启动和服务管理的根。理解 PID 1,有助于解释服务为什么开机启动、孤儿进程由谁接管、僵尸进程为什么要看父进程,以及容器为什么需要正确处理信号和子进程回收。

别急,先让缓存热一下。