Skip to content

上下文切换机制

2026 大纲 二(二)6 上下文及其切换机制。条目是"上下文及其切换机制"——上下文本身是什么怎么切换是两个并列的要求。

换人这个动作,具体要搬哪些东西

调度那几节回答的是"下一个选谁"。选完之后还有一步没做:怎么换过去。

这一步看着机械,其实有个绕不开的问题:换人时到底要保存什么?

保存太多是白费力气(很多东西根本没变),保存太少则恢复不回来。 判据只有一句:这个东西会不会被下一个进程改掉,改掉之后原进程还能不能接着跑。

按这条判据,进程上下文分成三层,但只有寄存器上下文必须真正搬动—— 另外两层(内存管理信息、进程控制信息)只需要换指针,因为它们本来就分别存着。

⚠️ 现场必须存进 PCB,不能存在进程自己的栈里。理由有两条: 一是会撞上"要恢复栈指针,得先知道栈指针在哪"的循环依赖; 二是进程被换出到外存后,OS 就再也够不着它自己的那块空间了。

还有一处分工要分清:头尾两步由硬件做(中断隐指令保存 PC 与 PSW、 中断返回指令恢复它们),中间全是软件。判据和 中断和异常的处理那条一样—— 改了它就没法继续执行的东西,必须由硬件原子处理

最后是开销。它分直接(搬寄存器)与间接(TLB、Cache 冷启动)两块, 而间接那块通常大得多——这也解释了为什么同进程的线程切换便宜: 不换地址空间,最大的那块间接开销整块消失。

一、进程上下文的三层结构

层次包含什么存放在哪里切换时怎么处理
① 用户级上下文程序块(可执行的机器指令序列)、数据块(进程可访问的信息)、共享主存区(进程通信用)、用户栈(函数调用信息)占用进程的虚存空间不搬动,只需切换地址映射(换页表基址寄存器),让 CPU"看到"另一套虚存空间
② 寄存器上下文处理器状态寄存器 PSW指令计数器 PC栈指针 SP通用寄存器CPU 内部必须逐个搬进 PCB,因为 CPU 里只有一套,新进程要用
③ 系统级上下文PCB主存管理信息(页表或段表)、核心栈(进程在内核运行时的工作区)等 OS 管理进程所需的信息内核空间大部分不搬动,只需把指针换成新进程的

最后一列解释了开销的来源:切换的直接开销 = 搬一套寄存器 + 换几个指针,量并不大;真正贵的是换指针之后的连锁反应(TLB 与 Cache 全部失效),见 §四。PCB 的组织见 进程的组织与控制

二、切换过程:哪一步是硬件做的

第②步必须由硬件做:中断隐指令不是一条真正的机器指令,而是 CPU 在响应中断时自动执行的一串硬件动作,程序员写不出来也拦不住——软件要执行任何指令都会改写 PC 和 PSW,等软件跑起来时原值早没了。详见 中断和异常的处理。第③步交给软件是因为通用寄存器数量多、哪些需要保存与具体实现有关。

三、切换的时机

触发原因属于哪类调度时机抢占式才有?
进程终止当前进程不能继续占 CPU
进程阻塞(发出 I/O 请求、执行 Block 原语)当前进程不能继续占 CPU
时间片用完(时钟中断)规则不许它继续占
被更高优先级进程抢占出现了更该占 CPU 的

调度的时机完全对应——调度决定"要不要换人",上下文切换是"换人"这个决定的执行

四、切换开销:两块性质完全不同的东西

直接开销间接开销
是什么执行切换代码本身所花的时间切换完成之后,新进程因缓存冷启动而变慢的那部分损失
具体包含保存/恢复寄存器上下文(约上千条指令)、更新 PCB、进出队列、切换页表基址寄存器与核心栈指针TLB 冷启动(旧进程的表项全部作废,新进程要经历一段 TLB 缺失密集期)、Cache 冷启动(Cache 里全是旧进程的数据,新进程一开始几乎必然未命中)
发生在何时切换的那一瞬间切换后的一段时间内,逐渐衰减
能不能直接测能(测切换函数的执行时间)不能直接测,只能通过对比稳态性能折算
谁更大通常更小通常大得多
用一组数算出"忽略间接开销会把时间片下限估小五倍"(想量化总开销怎么反推时间片时展开)

设实测直接开销 δd=2 μs,把 TLB 与 Cache 冷启动造成的额外损失折算为 δi=8 μs

第一步:求总开销。 利用率公式里 δ 的含义是"每一个时间片要额外付出的、不产出计算的时间";冷启动期间新进程虽然在跑,但跑得比稳态慢,慢出来的那部分等价于没在算,所以折算后可并入 δ

δ=δd+δi=2+8=10 μs

第二步:q=10 ms =10000 μs

完整口径: 1000010000+10=99.90%,只算直接开销: 1000010000+2=99.98%

高估 0.08 个百分点——时间片很大时间接开销被稀释了。

第三步:q=100 μs

完整口径: 100100+10=90.91%,只算直接开销: 100100+2=98.04%

高估 7.13 个百分点δq 的比值决定误差,q 缩小 100 倍,误差放大近 90 倍——时间片越小,忽略间接开销的误差越大

第四步:反推时间片下限。

qq+10  0.99  0.01q9.9  q990 μs1 ms

只用 δd=2 μs 反推会得到 q198 μs,只有真实要求的五分之一;按它设时间片,实际利用率会掉到 98% 左右。δ 里真正说了算的往往是看不见的那一半——这也解释了处理器亲和性为什么值得专门设计,它保护的正是这块间接开销。

考点速记

  1. 进程上下文分三层,切换时只有寄存器上下文必须真正搬动,另外两层只换指针。
  2. ⚠️现场必须存进 PCB:一是会撞上"恢复栈指针得先知道栈指针"的循环依赖,二是进程换出外存后 OS 就够不着它自己的空间了。
  3. 切换过程头尾两步由硬件(中断隐指令保存 PC/PSW、中断返回指令恢复),中间全是软件。判据:改了它就没法继续执行的东西必须由硬件原子处理
  4. ⚠️发生调度不一定发生切换,发生切换必然先发生了调度(选中的还是原来那个进程时就不切换)。
  5. 开销分直接与间接两块:直接是搬寄存器,间接是 TLB / Cache 冷启动,⚠️间接那块通常大得多δ=δd+δi 决定时间片的下限。
  6. ⚠️同进程内的线程切换便宜,只因不换地址空间——页表基址寄存器不动、TLB 不失效,最大的那块间接开销整块消失。
  7. ⚠️页式虚存下切换时要换的通用寄存器(各进程的计算现场不同)、程序计数器(各进程执行到哪不同)、页表基址寄存器(各进程页表不同)。不需要换的是内核中断向量表基址寄存器——中断向量表全系统只有一份,跟哪个进程在跑毫无关系。

这一节在真题里被考过的形式

只出过一道题,但它把"什么要换、什么不要换"这条判据考得很干净。

  • 问页式虚存系统发生上下文切换时不需要保存或切换的是什么(2025-23)。答内核中断向量表基址寄存器。⚠️ 判据是速记第七条——问"这个东西是不是每个进程各有一份":通用寄存器、程序计数器显然各进程不同;页表基址寄存器也是(每个进程一张页表);而中断向量表是全系统唯一的,换谁上来它都指向同一张表,自然不用动。
  • 另有两处会作为背景出现:发生调度不一定发生切换(速记第四条,在调度的基本概念也提过);线程切换比进程切换便宜的原因(速记第六条,在线程已考过)。

复习优先级必须拿满,判据只有一句——问"这个东西是不是每个进程各有一份"。 是的就要换,全系统共用的就不用。速记第三条(头尾硬件、中间软件)与 中断和异常的处理是同一条判据的第二次应用。 第五条那个直接/间接开销的划分在时间片轮转q 的下限时用得上。

易错:认为中断向量表基址寄存器也要随进程切换。中断向量表全系统只有一份,与进程无关。

易错:认为页表基址寄存器不用换。每个进程一张页表,必须换。

易错:把现场存在进程自己的栈里。必须存进 PCB——否则"恢复 SP 得先知道 SP"是死循环。

易错:认为切换开销主要是搬寄存器。间接开销(TLB / Cache 冷启动)通常大得多

易错:认为发生调度就一定发生切换。选中的还是原进程时不切换

教材出处
  • 孙钟秀、费翔林《操作系统教程》第 6 版 2.3.2 进程上下文(进程上下文的定义与用户级/寄存器/系统级三层划分及各层的具体内容),印刷 p58
  • 汤小丹《计算机操作系统》3.3.1 进程调度的任务、机制和方式(进程调度三项任务、上下文切换器与"两对上下文切换"的口径、"每一次上下文切换所花时间大约可执行上千条指令"、用两组寄存器减少切换时间的硬件办法),印刷 p91–p92

相关知识

多处理机调度调度的基本概念与目标线程中断和异常的处理同步与互斥基本概念

真题练习

相关真题(3题)