在 Linux/Unix 操作系统中,进程管理是核心知识点,其中孤儿进程 与僵尸进程是面试高频考点。同时,为了让多任务并发执行,操作系统需要使用进程调度算法决定谁优先执行。本文将带你深入理解这些关键机制,并结合 CPU 调度逻辑进行说明。
前置说明:首先明白一点,无论是孤儿还是僵尸,他说的都是子进程。

一、孤儿进程(Orphan Process)
定义
简单来说就是父亲走了,那么儿子就没人管成为了孤儿,这时候就交由init线程替代作为他的父亲。
孤儿进程指:父进程已退出,但子进程仍在运行。
在 Linux 中,如果一个子进程变成了孤儿进程,系统会将其父进程重定向为 init 进程(PID = 1),并由 init 负责收养和回收。
特点总结
| 项目 | 描述 |
|---|---|
| 子进程状态 | 存活 |
| 父进程状态 | 已终止 |
| 是否造成资源泄漏 | 否(init 会回收) |
| 是否正常现象 | 是 |
孤儿进程属于正常机制,系统有能力安全托管,因此无危害。
二、僵尸进程(Zombie Process)
简单来说就是子进程死了,但是父亲没有及时通过wait()回收子进程,这时候子进程就成了占用位置的僵尸。
其中wait包含:1.如果子进程退出及时回收 2.如子进程没有退出,阻塞父进程去等子进程退出时再回收
定义
僵尸进程指:
子进程已执行结束,但父进程没有回收其资源(未调用 wait())
它会持有以下资源:
-
进程表项(PCB 部分信息)
-
退出状态码(供父进程读取)
特点总结
| 项目 | 描述 |
|---|---|
| 子进程状态 | 已死亡 |
| 父进程状态 | 存活但未 wait() |
| 是否浪费资源 | 是(占 PID 和 PCB 表项) |
| 是否危险 | 是,大量僵尸会耗尽 PID |
常见原因:父进程未处理 SIGCHLD 信号、逻辑缺陷导致未调用 wait() 。
三、孤儿进程 vs 僵尸进程对比总结
| 特性 | 孤儿进程 | 僵尸进程 |
|---|---|---|
| 子进程状态 | 正在运行 | 已经终止 |
| 父进程状态 | 已终止 | 正在运行 |
| 是否由 init 托管 | 是 | 否 |
| 是否会泄漏资源 | 否 | 是 |
| 是否属于异常 | 否 | 是 |
一句话快速记忆:
孤儿:父死了系统领养
僵尸:子死了没人回收
四、进程调度算法详解
首先要理解为什么会有系统调用:当应用程序需要访问内核资源(如文件或网络)时,会从用户态切换到内核态。
在多核 CPU 中,我们常说"8 核 16 线程",可以看出线程数量通常大于核心数。而一个核心同一时刻只能执行一个线程,所以操作系统必须决定哪个线程先获得执行机会,这就是进程调度算法 的作用。
注意:虽然名字叫进程调度,但线程才是 CPU 的实际执行单位。
操作系统使用调度算法决定在同一时刻 CPU 执行哪个进程。
分类如下:
1. 批处理系统调度算法(站在作业的角度考虑)
| 算法 | 类型 | 优点 | 缺点 |
|---|---|---|---|
| 先来先服务 FCFS | 非抢占式 | 实现简单 | 长作业阻塞短作业 |
| 最短作业优先 SJF | 非抢占式 | 平均等待时间最短 | 长作业可能被饿死 |
| 最短剩余时间优先 SRTF | 抢占式 | 策略更优 | 实现复杂、仍可能饥饿 |
适合:后台任务批量执行、无需立即响应的系统
2. 交互式系统调度算法(站在系统设定的角度考虑)
| 算法 | 优点 | 缺点 |
|---|---|---|
| 时间片轮转 RR | 响应好、适合多任务并发 | 上下文切换频繁,开销大 |
| 优先级调度 | 紧急任务优先 | 低优先级可能饥饿 |
| 多级队列调度 | 综合效率高 | 实现复杂 |
多级队列 = 优先级调度 + 时间片轮转
常用于桌面系统、移动 OS
五、CPU 调度与内核切换的关系
CPU 在以下情况会从 用户态 → 内核态 并可能触发调度:
| 触发方式 | 原因 | 示例 |
|---|---|---|
| 系统调用 | 用户程序主动请求内核服务 | read/write/network |
| 中断(外设事件) | 需要快速响应硬件 | 键盘、鼠标、网卡数据到达 |
| 异常 | 程序错误 | 除零、段错误 |
当进入内核后,内核调度器可能决定:
-
当前进程继续运行
-
让出 CPU 给优先级更高的进程