Appearance
进程状态与转换
2026 大纲 二(一)2 进程/线程的状态与转换。
一个进程此刻在干什么,只有三种可能
上一节把进程这个对象立起来了。可 OS 要管它,光有对象不够—— 得随时知道它现在处于什么处境,才能决定要不要给它 CPU。
处境看着五花八门(在算、在等键盘、在等内存、刚被创建、刚跑完), 但用两个追问就能把它们全部收拢:
第一问:它现在占着 CPU 吗? 占着 → 运行态。
第二问(不占 CPU 的那些):除了 CPU,它还缺别的东西吗? 什么都不缺、只等 CPU → 就绪态;还在等别的(I/O 完成、某个信号量、 某块内存)→ 阻塞态。
三个状态就是这两个追问的三个答案,一个不多一个不少。 再补上"正在被创建、还没准备好"的创建态和"跑完了、等着被回收"的终止态, 就是五状态模型。
状态本身不难,难的是转换——哪些转换合法、由什么事件触发。 这里有两条最容易搞混的分界,先立在前面:
"就绪 → 阻塞"永不发生。 阻塞的意思是"我发出了一个请求、要等结果", 而只有正在运行的进程才发得出请求。就绪态的进程连 CPU 都没有, 它什么也做不了,自然也无从等起。
"阻塞 → 运行"也永不发生。 等待的事件完成时,进程被唤醒成就绪态, 但它得排队等调度程序挑中它才能上 CPU。唤醒和调度是两件事。
交互可视化
一、五状态模型与六条合法转换
| 转换 | 触发条件 | 由谁完成 | 前提 |
|---|---|---|---|
| 创建→就绪 | 系统完成创建,资源分配到位 | 操作系统(创建原语) | 内存等资源允许 |
| 就绪→运行 | 调度程序选中该进程 | 调度程序 | — |
| 运行→就绪 | 时间片用完,或被更高优先级进程抢占 | 操作系统/调度程序 | 必须是抢占式调度 |
| 运行→阻塞 | 主动请求等待某事件(I/O、P 操作、申请资源失败) | 进程自身(主动) | 进程必须正在运行 |
| 阻塞→就绪 | 所等事件已发生(I/O 完成、V 操作) | 操作系统/中断处理程序(被动) | — |
| 运行→终止 | 正常结束、异常结束或被外界终止 | 进程自身/操作系统 | — |
时间片轮转、抢占式优先级这类算法必然是抢占式的,先来先服务、非抢占式短作业优先里不会出现"运行→就绪"。抢占与非抢占的分界见 调度的基本概念与目标。
二、挂起与七状态模型
挂起(Suspend)是把进程换出到外存、使之处于静止状态的操作,与之对应的是激活(Active)。四类发起者的具体场景:
| 发起者 | 场景 |
|---|---|
| 终端用户 | 用户发现自己程序运行可疑,希望暂停下来研究执行情况或修改程序 |
| 父进程请求 | 父进程要查看、修改某个子进程,或协调各子进程的活动 |
| 负荷调节的需要 | 系统负荷过重、已影响到实时任务的响应时,把不重要的进程挂起以保证系统正常运行 |
| 操作系统的需要 | OS 要检查资源使用情况或进行记账;以及虚拟存储系统中内存吃紧,把进程换出外存 |
引入挂起后,原来的就绪态和阻塞态各自按"在不在内存、参不参与调度"分裂成两个。"活动/静止"是汤小丹教材的命名,"挂起就绪/挂起阻塞"是另一种常见叫法,指的是同一批状态——两套名字都要认得:
| 教材命名 | 别称 | 含义 |
|---|---|---|
| 活动就绪 Readya | 就绪 | 未被挂起的就绪态,在内存中,可以接受调度 |
| 静止就绪 Readys | 挂起就绪 | 已被挂起,进程映像在外存,不再被调度执行 |
| 活动阻塞 Blockeda | 阻塞 | 未被挂起的阻塞态,在内存中等事件 |
| 静止阻塞 Blockeds | 挂起阻塞 | 已被挂起,进程映像在外存,同时还在等事件 |

图源:汤小丹《计算机操作系统》图 2-8 具有创建、终止和挂起状态的进程状态图,印刷 p39
对着图把完整的边清单过一遍(前四条直接由 Suspend / Active 两个原语给出):
| 转换 | 什么时候发生 |
|---|---|
| 活动就绪 → 静止就绪 | 挂起 |
| 静止就绪 → 活动就绪 | 激活(换入内存) |
| 活动阻塞 → 静止阻塞 | 挂起 |
| 静止阻塞 → 活动阻塞 | 激活 |
| 执行 → 静止就绪 | 正在运行的进程被挂起(如用户或父进程发出 Suspend) |
| 活动阻塞 → 活动就绪 | 事件完成(这就是五状态里的"阻塞→就绪") |
| 静止阻塞 → 静止就绪 | 进程在外存期间,它等待的事件完成了 |
| 创建 → 活动就绪 | 系统性能和内存容量都允许,创建工作全部完成,直接进内存待调度 |
| 创建 → 静止就绪 | 考虑当前资源状况与性能要求,不给新建进程分配主存,先放外存、不参与调度——此时创建工作尚未完成 |
三、线程的状态与转换
| 线程库支持的线程(用户级线程) | 内核支持的线程(内核级线程) | |
|---|---|---|
| 谁维护线程状态 | 用户空间的线程库 | 内核 |
| 内核眼里的调度对象 | 只有进程 | 每个线程 |
| 一个线程执行阻塞式系统调用 | 内核不知道有线程,把整个进程置为阻塞态;同进程其余线程即使在线程库里记着"就绪",也拿不到 CPU | 内核只把这一个线程置为阻塞态,同进程的其他线程照样可被调度 |
| 结论 | 一个阻塞,全部阻塞 | 一个阻塞不影响其他 |
两类线程的实现细节见 线程;执行状态转换的那组原语与状态队列的三种组织方式见 进程的组织与控制。
一条含挂起的完整事件序列,逐步走出每次转换与转换次数统计(想在时间轴上看清状态怎么跳时展开)
单处理机系统采用抢占式优先级调度,优先级 P1 > P2 > P3。三个进程创建完成后依次发生:t0 调度程序开始工作;t1 P1 发出 I/O 请求;t2 P1 的 I/O 完成;t3 内存紧张,操作系统挂起 P3;t4 P1 执行完毕;t5 内存恢复充裕,操作系统激活 P3。
| 时刻 | 发生的转换 | 这一步为什么这么走 |
|---|---|---|
| t0 | P1:就绪→运行 | 三个都在就绪队列,抢占式优先级下选优先级最高的 P1 |
| t1 | P1:运行→阻塞 P2:就绪→运行 | I/O 请求只能由正在运行的进程发出,所以是"运行→阻塞"而非"就绪→阻塞";CPU 空出来必须重新调度,就绪者中 P2 优先级最高 |
| t2 | P1:阻塞→就绪 P2:运行→就绪 P1:就绪→运行 | 事件完成只能把 P1 送回就绪(没有"阻塞→运行");P1 优先级高于正在运行的 P2,抢占式下 P2 被踢回就绪;再调度,P1 上 CPU |
| t3 | P3:活动就绪→静止就绪 | 挂起的是就绪态进程,落到静止就绪;P3 本来就没在 CPU 上,不影响运行者 |
| t4 | P1:运行→终止 P2:就绪→运行 | 正常结束;CPU 空出,就绪者中只剩 P2(P3 在静止就绪,不参与调度) |
| t5 | P3:静止就绪→活动就绪 | 激活换入内存,重新参与调度;但 P2 正在运行且此刻无更高优先级者抢它,P2 继续 |
共 10 次状态转换:就绪→运行 4 次、运行→就绪 1 次、运行→阻塞 1 次、阻塞→就绪 1 次、运行→终止 1 次、活动就绪→静止就绪 1 次、静止就绪→活动就绪 1 次。末态:P1 终止、P2 运行、P3 就绪。
把"抢占式"改成"非抢占式",t2 处 P2 不会被踢下 CPU(没有"运行→就绪"这条边),P1 只能停在就绪态等 P2 让出,转换次数减少 2 次。调度方式是这类推演的隐含前提,题干不写就要自己认出来。
考点速记
- 三状态由两个追问推出:占不占 CPU(运行态)、除 CPU 外资源齐不齐(就绪 / 阻塞)。五状态再补上创建态与终止态。
- ⚠️三类转换永不发生:就绪 → 阻塞(就绪态没有 CPU,发不出请求)、阻塞 → 运行(要先被唤醒成就绪,再等调度)、终止态 → 任何状态。
- ⚠️只有"运行 → 就绪"依赖抢占式调度:时间片用完、被高优先级进程抢占,都是这一条。它不是进程自己让出的——进程主动让出(等 I/O、等信号量)走的是"运行 → 阻塞"。
- "运行 → 阻塞"是进程自己发起的(执行
P操作失败、申请内存失败、启动 I/O 后等待);"阻塞 → 就绪"是别人唤醒的(I/O 完成、别的进程V了信号量、别的进程退出临界区释放了资源)。 - 唤醒 ≠ 调度:唤醒只是把进程从阻塞队列挪到就绪队列,能不能上 CPU 还要看调度程序。所以"读磁盘操作完成后 OS 必做的是把进程状态改为就绪态",不是让它立刻运行、也不是调整优先级或时间片。
- 挂起的动因是"要让它静止下来"(用户请求、父进程请求、负载调节、OS 自身需要四类发起者),换出外存只是手段。
- ⚠️挂起与阻塞是正交的两个维度:2×2 组合出活动就绪 / 静止就绪 / 活动阻塞 / 静止阻塞,加上运行、创建、终止构成七状态模型。"挂起"不等于"阻塞"。
- 线程有执行 / 就绪 / 阻塞三态且转换与进程相同,但没有独立的挂起态(挂起是对整个进程的资源操作)。
- 一个线程阻塞会不会拖垮全进程,取决于内核认不认识线程:用户级线程内核不认识 ⇒ 一个阻塞则整个进程阻塞;内核级线程内核认识 ⇒ 只阻塞它自己。
这一节在真题里被考过的形式:
三道题都在考状态转换的触发事件,而且三道题分别对应速记第三、四、五条—— 可以说这一节的全部考法就是"这件事发生后,进程从哪个态到哪个态,由谁发起"。
- 问会导致进程从执行态变为就绪态的事件(2015-25)。答被高优先级进程抢占。⚠️ 另三项(执行
P操作、申请内存失败、启动 I/O 设备)全都是"运行 → 阻塞"——它们的共同点是进程自己发起、然后等一个结果。判据是速记第三、四条:运行→就绪只由抢占引起,运行→阻塞才是进程自己让出的。 - 问读磁盘操作完成后 OS 针对该进程必做的操作(2014-26)。答修改进程状态为就绪态。⚠️ 另三项都是"看起来合理但不必做":降低优先级、分配用户内存空间、增加时间片——I/O 完成这件事只触发一个动作,就是唤醒。而唤醒的结果是就绪不是运行(速记第五条)。
- 问哪些事件可能将进程唤醒(2019-24)。答 I/O 结束 + 某进程退出临界区两条。⚠️**"当前进程的时间片用完"不能唤醒任何人——它引起的是当前进程从运行变就绪,而唤醒说的是把别的进程从阻塞变就绪。这道题的设计点就是分清"谁的状态变了"**。
复习优先级:必须拿满,判据只有一句——看这件事是"进程自己在等"还是"别人来叫它": 自己等 ⇒ 运行→阻塞;别人叫 ⇒ 阻塞→就绪;被抢走 ⇒ 运行→就绪。 速记第二条那三类永不发生的转换是判断题的固定素材。 七状态与线程状态至今没单独考过,理解第七、九条即可。
易错:认为"执行 P 操作""申请内存失败""启动 I/O"会让进程变就绪态。它们全都进阻塞态——只有被抢占才是运行→就绪。
易错:认为唤醒后进程立刻运行。唤醒只把它挪到就绪队列,上不上 CPU 要看调度。
易错:认为"时间片用完"会唤醒进程。它让当前进程从运行变就绪,与唤醒别人无关。
易错:认为就绪态可以直接变阻塞态。就绪态没有 CPU,发不出任何请求。
易错:认为阻塞态可以直接变运行态。必须先被唤醒成就绪,再等调度挑中。
易错:把"挂起"当成"阻塞"。两者正交——可以活动阻塞,也可以静止就绪。
易错:认为一个线程阻塞必然拖垮整个进程。取决于内核认不认识线程——内核级线程不会。
教材出处
- 汤小丹《计算机操作系统》2.2.2 进程的基本状态及转换,印刷 p36:就绪、执行、阻塞三种状态的定义,以及"多处理机系统中则有多个进程处于执行状态"
- 汤小丹《计算机操作系统》2.2.3 挂起操作和进程状态的转换,印刷 p38:引入挂起的四类原因(终端用户、父进程请求、负荷调节、操作系统需要);活动就绪 Readya / 静止就绪 Readys / 活动阻塞 Blockeda / 静止阻塞 Blockeds 的命名与四条转换;"创建→静止就绪"的条件
- 汤小丹《计算机操作系统》图 2-8 具有创建、终止和挂起状态的进程状态图,印刷 p39
- 汤小丹《计算机操作系统》2.7.3 线程的状态和线程控制块,印刷 p78:线程运行的三个状态,"线程状态之间的转换和进程状态之间的转换是一样的";"在把某个进程挂起时,该进程中的所有线程也都将被挂起"
- 汤小丹《计算机操作系统》2.8.1 线程的实现方式,印刷 p80:用户级线程"当线程执行一个系统调用时,不仅该线程被阻塞,而且进程内的所有线程会被阻塞"
相关知识
进程基本概念|进程的组织与控制|调度的基本概念与目标|线程|多处理机调度