Appearance
Init 进程
Init 进程是 Linux 内核启动后拉起的第一个用户空间进程,PID 固定为 1。现代系统中它通常是 systemd。它的职责不是处理普通业务请求,而是启动系统、管理服务、收养孤儿进程,并在系统关闭时协调收尾。
PID 1 的位置
启动链路可以简化为:
- 固件加载引导程序。
- 引导程序加载内核。
- 内核初始化硬件、内存、调度器和根文件系统。
- 内核启动第一个用户空间进程,也就是 PID 1。
- PID 1 继续启动系统服务和登录环境。
如果 PID 1 出问题,影响的是整个系统级别的启动和服务管理。
Init 系统演进
| 类型 | 特点 | 现状 |
|---|---|---|
| SysV Init | 按脚本和运行级别顺序启动 | 老系统中常见 |
| Upstart | 事件驱动,曾用于部分发行版 | 现在较少见 |
| systemd | unit、依赖、并行启动、统一日志 | 主流发行版默认 |
判断当前 PID 1:
bash
ps -p 1 -o pid,comm,args
cat /proc/1/commPID 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,有助于解释服务为什么开机启动、孤儿进程由谁接管、僵尸进程为什么要看父进程,以及容器为什么需要正确处理信号和子进程回收。
