第 2 章 名词库
这一页是复习主入口。 目标是把第 2 章的名词收全,并把每个词的边界和适用范围钉死。
每条最多四行:
- 是:一句话定义
- 不是:划掉最常见的错误理解
- 易混:成对的对手是谁
- 范围:该结论在什么条件下才成立(只在有范围限制时才出现,务必留意)
正文用
[[os-glossary-ch02#进程 (Process)|进程]]这样的锚点链接进来,鼠标悬停即可预览。建设进度:✅ 2.1 进程与线程 ✅ 2.2 CPU 调度 ✅ 2.3 同步与互斥 ✅ 2.4 死锁 (第 2 章完整)
2.1.1 进程的概念和特征
多道程序设计
- 是:内存中同时存放多道程序,使它们交替占用 CPU,以便某道程序等待 I/O 时 CPU 转去执行别的程序。
- 不是:不等于”同时执行”。单处理机下任一时刻仍只有一道程序在 CPU 上跑。
- 易混:它是并发的实现前提,也是本章一切复杂性(异步、互斥、死锁)的总源头。
作业 (Job)
- 是:用户提交给系统的一个独立的计算任务,包含程序、数据和作业说明书。作业驻留在外存的后备队列中。
- 不是:作业不是进程。作业没有 PCB、不占内存、不参与处理机调度。
- 易混:↔ 进程。作业被高级调度选中后才被建立成进程。
- 范围:“作业”这一概念主要用于批处理系统。交互式系统中通常直接讨论进程。
进程 (Process)
- 是:程序在某个数据集合上的一次运行过程,是系统进行资源分配和调度的独立单位。
- 不是:不是”正在运行的程序”这么简单——同一个程序跑两次是两个进程;一个进程也可以在生命周期中执行多个程序(
exec换掉代码段后,进程仍是原来那个)。 - 易混:↔ 程序(静态 vs 动态);↔ 进程实体(进程是”过程”,进程实体是”这一时刻的快照”)。
- 范围:“进程是调度的基本单位”这句话只在未引入线程时成立。引入线程后调度单位变为线程,进程仅保留资源分配单位的身份。
程序 (Program)
- 是:存放在外存上的一段静态指令和数据的集合。
- 不是:不占有 CPU、不拥有资源、没有状态。
- 易混:↔ 进程。教材”进程是程序的一次执行”里,“一次”才是重点。
进程控制块 (PCB, Process Control Block)
- 是:操作系统为管理进程而设置的数据结构,存放进程标识、状态、调度信息、资源清单、现场信息等。PCB 是进程存在的唯一标志。
- 不是:不在用户地址空间里,进程自己碰不到;也不是”进程的全部”,它只含管理信息,不含代码和用户数据。
- 易混:↔ 进程实体(PCB 是进程实体的一部分);↔ TCB。
进程实体(进程映像)
- 是:程序段 + 相关数据段 + PCB 三者的总和,是进程在某一时刻的静态快照。
- 不是:不是动态概念。“进程”是动态的过程,“进程映像”是按下暂停键后看到的样子。
- 易混:↔ 进程上下文。高频对:映像强调”内存里有什么”,上下文强调”恢复执行需要什么”。
进程的五个特征
- 是:动态性(最基本特征)、并发性、独立性、异步性、结构性。
- 不是:最基本的特征是”动态性”而非”并发性”——这是选择题常设的陷阱。
- 易混:↔ 下面”操作系统的四个特征”(并发、共享、虚拟、异步),两组特征分属不同主体,不要混答。
并发 (Concurrency)
- 是:多个进程在同一时间段内都在推进。宏观上同时,微观上(单核)交替执行。
- 不是:不是同一时刻真的一起跑。
- 易混:↔ 并行。单核可以并发,不能并行。
并行 (Parallelism)
- 是:多个进程在同一时刻真正同时执行,需要多个处理单元(多核/多处理机)。
- 不是:不是并发的同义词,是并发的一个特例。
- 易混:↔ 并发。
- 范围:只有在多处理机或多核环境下才谈得上并行。 题干出现”单处理机”时,一切”并行”选项都可直接排除。
共享 (Sharing)
- 是:系统资源可被内存中多个并发执行的进程共同使用。分两类:互斥共享(一段时间内只允许一个进程访问,如打印机)与同时共享(宏观上允许多进程同时访问,如磁盘、可重入代码)。
- 不是:“同时共享”在微观上通常仍是交替访问,不是真正的同时。
- 易混:↔ 临界资源。互斥共享的资源就是临界资源。
虚拟 (Virtuality)
- 是:把一个物理实体变成多个逻辑实体(时分复用,如虚拟处理机),或把多个物理实体抽象成一个逻辑实体(空分复用,如虚拟内存)。
- 不是:虚拟出来的东西没有实际物理存在,只是用户感觉上存在。
- 易混:虚拟必须以并发为前提——没有并发就无需也无法虚拟。
异步性 (Asynchronism)
- 是:进程以不可预知的速度向前推进——何时被调度走、等多久资源,均不确定。
- 不是:不是”出错”,而是多道程序环境下正常且必然的现象。
- 易混:异步性是原因,失去封闭性和失去可再现性是后果。
- 范围:进程的相对推进速度由调度策略决定,进程自身无法控制。
封闭性
- 是:程序独占运行时,执行结果只由初始条件决定,不受外界影响。这是单道程序才有的性质。
- 不是:并发环境下没有封闭性。
- 易混:↔ 可再现性。准确表述是:并发进程共享变量,其执行结果与速度有关。
可再现性
- 是:同样的初始条件,无论运行多少次、环境如何,都得到同样的结果。
- 不是:并发环境下不再具备。
- 易混:封闭性是因,可再现性是果。失去封闭性必然失去可再现性,反之不必然。
2.1.2 进程的组成
链接方式 / 索引方式
- 是:PCB 的两种组织方式。链接方式把同状态的 PCB 用指针串成队列;索引方式为每种状态建一张索引表指向对应 PCB。
- 不是:不是二选一的对立,实际系统可混用。
- 易混:索引方式查找快,但需额外维护索引表。
就绪队列 / 阻塞队列
- 是:按状态组织 PCB 形成的队列。就绪队列可按优先级组织成多条;阻塞队列通常按等待事件分成多条(等打印机一条、等磁盘一条)。
- 不是:阻塞队列不是只有一条。分开的目的是释放某资源时可直接到对应队列取队首唤醒,无须遍历筛选。
- 易混:这正是”释放一台打印机只唤醒一个进程”能够高效实现的原因。
进程上下文 (Context)
- 是:进程运行时 CPU 及相关寄存器的现场信息加上内核中的控制信息——即”要让该进程从断点继续执行,必须保存和恢复的全部内容”。
- 不是:中断向量不属于进程上下文。它是全系统共享一份的固定表,不随进程切换而保存恢复。
- 易混:↔ 进程映像。映像 = 内存里有什么;上下文 = 切换时要存什么。二者有交集但互不包含:代码段在映像不在上下文,CPU 寄存器现值在上下文不在映像。
正文段 / 数据段 / BSS 段 / 堆 / 栈
- 是:进程地址空间的五个区域。正文段放代码和常量(只读);数据段放已初始化的全局与静态变量;BSS 放未初始化的全局与静态变量;堆放动态分配空间(向高地址增长);栈放局部变量、参数、返回地址(向低地址增长)。
- 不是:BSS 不占可执行文件体积(只记录需要多大,装入时清零),但占内存。
- 易混:教材也有粗粒度三分法(正文段/堆/栈),把两类全局变量都算进正文段。看选项给的粒度决定用哪一档。
静态数据 / BSS
- 是:
static变量和全局变量具有静态存储期,程序启动即存在、结束才消亡。去处只看是否被初始化:初始化为非零 → 数据段;未初始化或初始化为 0 → BSS。 - 不是:
const不一定被展开到代码中。基本类型且未取地址时编译器常做常量折叠;一旦取地址或为数组/结构体,则必须占据存储空间,通常在只读数据段(.rodata)。 - 易混:考试层面只需记住”常量在只读区”。
2.1.3 进程的状态与转换
就绪态 (Ready)
- 是:进程已获得除 CPU 之外的一切所需资源,只等 CPU。
- 不是:不是”什么都没准备好”,恰恰相反——万事俱备,只欠 CPU。
- 易混:↔ 阻塞态。判据只有一个:缺的是不是 CPU。
运行态 (Running)
- 是:进程正在 CPU 上执行。
- 不是:不是”恰好一个”。单处理机下运行态进程数为 0 个或 1 个,全部阻塞或死锁时为 0。
- 易混:“至多一个” ✅ 正确 / “有且仅有一个” ❌ 错误。
- 范围:“至多一个”这一结论仅限单处理机。n 个处理机下最多 n 个进程处于运行态。
阻塞态(等待态)
- 是:进程因等待某事件(I/O 完成、获得资源、等信号)而暂时无法运行,此时即使把 CPU 给它也没用。
- 不是:不是”被调度走了”。被调度走是就绪,不是阻塞。
- 易混:↔ 挂起态(阻塞看等不等事件,挂起看在不在内存)。
创建态
- 是:进程正在被创建——已申请 PCB 并填写部分信息,但资源尚未分配完毕,还不能被调度。
- 不是:创建态的进程不在就绪队列里,不参与调度。
- 易混:创建完成后转入就绪态,不会直接转入运行态。
结束态
- 是:进程正在从系统中消失——已停止运行,操作系统正在回收其资源,PCB 尚未删除。
- 不是:PCB 被删除后进程才真正不存在;结束态时 PCB 仍在。
- 易混:僵尸进程即停留在结束态、PCB 未被父进程回收的进程。
状态转换的四条合法边
- 是:就绪→运行(被调度,进入运行态的唯一途径)、运行→就绪(时间片到/被抢占)、运行→阻塞(主动请求得不到满足)、阻塞→就绪(被动,事件完成后被唤醒)。
- 不是:阻塞→运行不存在;就绪→阻塞不存在。这两条是最常考的”不可能转换”。
- 易混:运行→阻塞由进程自己调用阻塞原语(主动);阻塞→就绪由别人执行唤醒原语(被动)。方向别记反。
挂起态 (Suspend)
- 是:进程被换出到外存,不再占用内存。分静止就绪、静止阻塞。
- 不是:不是阻塞的同义词。挂起看在不在内存,阻塞看等不等事件——两个维度正交。
- 易混:由此组合出活动就绪、静止就绪、活动阻塞、静止阻塞四种(七状态模型)。
活动就绪 / 静止就绪 / 活动阻塞 / 静止阻塞
- 是:三态与”是否在内存”两个维度的组合。活动=在内存,静止=已换出到外存。
- 不是:静止就绪的进程不能直接被调度上 CPU,必须先被换回内存变成活动就绪。
- 易混:静止阻塞的进程即使等待事件完成,也只能转为静止就绪,而非直接就绪可运行。
2.1.4 进程控制
原语 (Primitive)
- 是:由若干条指令构成、完成特定功能的程序段,执行期间不可中断,具有原子性。用关中断/开中断实现。
- 不是:不是”很快的函数”。快不快无所谓,不可分割才是本质。
- 易混:↔ 系统调用(系统调用是接口,原语是实现手段)。
- 范围:关中断只能屏蔽外部中断,不能屏蔽内部异常;且原语必须短,否则影响系统响应和计时精度。
进程创建
- 是:申请空白 PCB → 为新进程分配资源 → 初始化 PCB → 插入就绪队列。四类来源:用户登录、作业调度、系统提供服务、用户程序请求。
- 不是:不是”把程序装入内存”。在请求分页系统中代码可能等到访问时才由缺页中断调入。
- 易混:作业调度这一项中,调度程序是常驻的发起者,被创建的是被选中的作业。
进程终止
- 是:三类事件——正常结束(自行
exit)、异常结束(越界、保护错、非法指令、特权指令错、运行超时、算术错、I/O 故障)、外界干预(kill、父进程终止)。 - 不是:异常结束的各项由硬件检测后报告给 OS,不是 OS 主动巡查发现的。
- 易混:越界/保护错由 MMU 检测;非法指令/特权指令错由 CPU 译码检测;算术错由 ALU 检测;运行超时靠时钟中断;I/O 故障由设备控制器报告。
阻塞原语 / 唤醒原语
- 是:阻塞原语保存现场、改状态、挂入等待队列并转调度;唤醒原语从等待队列摘下、改状态、挂入就绪队列。
- 不是:唤醒不能由进程自己完成——阻塞后它一条指令都执行不了。
- 易混:二者必须成对使用。阻塞后无人唤醒即永久等待,这是死锁与饥饿的源头。
进程切换 vs 模式切换
- 是:进程切换 = 换掉当前运行的进程(保存 A 的现场、恢复 B 的现场、切换页表、刷新 TLB);模式切换 = 同一进程从用户态进入内核态或返回。
- 不是:模式切换不一定引起进程切换。系统调用进内核,处理完通常还回到原进程。
- 易混:进程切换一定伴随模式切换,反之不成立。 这是全书最高频的边界之一。
- 范围:进程切换只能在内核态完成,因为它要访问 PCB 和页表基址寄存器等受保护资源。
父进程 / 子进程 / 进程树
- 是:由某进程创建出的新进程称为其子进程,创建者为父进程;由此形成层次结构即进程树。
- 不是:Windows 不支持进程的层次结构,各进程地位相同;层次结构主要见于 UNIX/Linux。
- 易混:
fork创建子进程(复制父进程地址空间),exec用新程序替换当前进程的地址空间——exec不创建新进程。
2.1.5 进程的通信
低级通信 vs 高级通信
- 是:判据是一次能传多少信息。低级通信只能传极少量控制信息(信号量 P/V、信号),效率低且对用户不透明;高级通信能传大批量数据,由 OS 封装接口(共享存储、消息传递、管道)。
- 不是:“低级=基于数据结构”不是指”用了什么数据结构实现”,而是指所传递的东西本身就是一个很小的数据结构,容量被其大小卡死。
- 易混:↔ 直接/间接通信。这是两条独立的分类线:一条看数据量,一条看要不要指名收件人。
共享存储 (Shared Memory)
- 是:两个进程各自把同一块物理内存映射进自己的地址空间,直接读写完成通信。三种方式中速度最快。
- 不是:OS 不负责互斥。同步须由进程自己用 P/V 或锁完成。
- 易混:↔ 管道(管道的同步由 OS 自动完成);↔
ptrace式内存访问(共享存储需双方合意,ptrace是单方面侵入且需权限)。 - 范围:教材把它细分为基于共享数据结构(容量小,属低级通信)与基于共享存储区(容量大,属高级通信)——同一个”共享存储”标题下横跨了低级与高级两档,答题时注意题干问的是哪一种。
消息传递 (Message Passing)
- 是:以格式化的消息(消息头 + 消息体)为单位,通过
send/receive原语交换数据,OS 负责底层传输。 - 不是:不是”一定要走网络”。同机进程间同样使用消息传递。
- 易混:需经内核两次拷贝(发送方→内核缓冲→接收方),因此比共享存储慢。
直接通信 vs 间接通信
- 是:直接通信
send(P2, msg)把消息挂到目标进程的消息缓冲队列,必须指名收件人;间接通信send(信箱A, msg)把消息发到信箱,谁来取都行。 - 不是:间接通信不等于低级通信,二者是不同维度。
- 易混:间接通信下收发双方不必知道对方,也不必同时在场——这是”解耦”的确切含义,也是与消息队列(MQ)对应的那一层语义。
信箱 (Mailbox)
- 是:独立于收发双方的中间实体,属于消息传递中的间接通信,是高级通信。
- 不是:不是低级通信,也不是共享存储。
- 易混:↔ MQ。信箱是同机内由内核维护的内存结构,不具备 MQ 的跨机、持久化、重试确认等工程特性。
管道 (Pipe)
- 是:一个固定大小的内核缓冲区,被当作特殊文件读写,半双工,一端写一端读。写满则写阻塞,读空则读阻塞。
- 不是:管道不是共享内存。数据读走即消失,不能反复读同一位置;也没有广播语义——多个读者时一份数据只被其中一个读到。
- 易混:↔ 共享存储(管道流式、一次性;共享存储可反复读)。
tee能一份输入送多处,靠的是用户态自行复制,恰好反证管道无广播能力。 - 范围:管道的同步互斥由 OS 自动完成,这一点与共享存储正好相反,是最高频的一对。
匿名管道 / 命名管道 (FIFO)
- 是:匿名管道无名字,只能用于有亲缘关系的进程(父子进程,通过
fork继承文件描述符),即 shell 中的|;命名管道有路径名,任意进程均可使用。 - 不是:
>重定向不是管道——它把 stdout 换成一个文件,走的是文件系统。 - 易混:
ls | grep x中 shell 创建的是匿名管道。
信号 (Signal)
- 是:OS 发给进程的一种异步通知,只传递”发生了某类事件”这一语义,内容仅为一个编号。
- 不是:不传数据,不是消息队列,不是共享内存;也不是 Qt 的 signal 或 JS 的事件——那些是纯用户态、同进程内的回调机制,内核并不知情。
- 易混:三种处理方式为执行默认操作、捕捉并自定义处理、忽略。但
SIGKILL(9) 与SIGSTOP(19) 不可捕捉、不可忽略,否则无法强制终止流氓进程。 - 范围:信号在”从内核态返回用户态之前”被检测。因为信号位图在 PCB(内核空间)中,只有内核态才有资格读取;且这个时机不额外增加开销。代价是信号处理存在延迟。
2.1.6 线程和多线程模型
线程 (Thread)
- 是:进程内的一条执行流,是调度的基本单位;同进程内的线程共享地址空间和大部分资源,各自私有程序计数器、一组寄存器、栈及 TCB。
- 不是:线程不是资源分配的基本单位(那仍是进程)。
- 易混:“资源分配单位 = 进程,调度单位 = 线程” 是引入线程后最核心的一句话。
- 范围:“线程是调度的基本单位”仅在内核级线程语境下成立。用户级线程对内核不可见,内核调度的仍是进程。
线程控制块 (TCB)
- 是:记录线程标识、现场、状态、优先级等信息的数据结构。
- 不是:TCB 比 PCB 小得多——因为线程不拥有资源,无须记录资源清单。
- 易混:TCB 的位置决定线程类型:在用户空间即用户级线程,在内核空间即内核级线程。
用户级线程 (ULT)
- 是:由用户态线程库管理,内核完全不知其存在。切换无须进内核,开销极小,且调度策略可由应用自定制。
- 不是:一个线程阻塞会导致整个进程阻塞(内核只看到进程),且无法利用多核并行(内核以进程为单位分配 CPU)。
- 易混:↔ 内核级线程。判据:内核知不知道。
- 范围:能引起 ULT 切换的必须是”用户态就能决定并执行”的事件(如线程同步)。系统调用、I/O 请求、异常处理都会陷入内核,内核只认进程,因此都不能引起 ULT 切换。
内核级线程 (KLT)
- 是:由内核管理和调度,TCB 在内核中。一个线程阻塞不影响同进程其他线程,可真正并行。
- 不是:切换开销不比 ULT 小——所有线程管理操作都要经系统调用进内核。
- 易混:JVM 的平台线程是 1:1(一个 Java 线程对应一个内核线程);虚拟线程是在其上做的 M:N 用户态调度。
线程库
- 是:在用户态实现线程创建、调度、同步的函数库,是用户级线程的管理者。
- 不是:线程库位于用户空间,内核不参与其调度决策。
- 易混:内核级线程不依赖线程库调度,而由内核调度程序直接管理。
多线程模型
- 是:多对一、一对一、多对多,描述用户级线程与内核级线程的映射关系。
- 不是:多对一模型下不能并行,且一个线程阻塞则全进程阻塞。
- 易混:一对一并发度最高但创建开销大且内核线程数有上限;多对多兼顾两者。
- 范围:考题固定套路——问”哪种模型下一个线程阻塞会导致整个进程阻塞”,答多对一。
轻量级进程 (LWP)
- 是:多对多模型中位于用户级线程与内核级线程之间的中间层,可视为内核支持的、供用户线程附着运行的”虚拟处理器”。
- 不是:LWP 不是用户级线程,它由内核支持。
- 易混:一个进程可有多个 LWP,每个 LWP 对应一个内核级线程。
套管程序 (Jacketing)
- 是:把阻塞式系统调用改造成非阻塞式的技术,用以缓解用户级线程”一个阻塞则全进程阻塞”的缺陷。
- 不是:它不能根本消除该缺陷,只是绕开。
- 易混:JDK 虚拟线程把标准库阻塞点改写为非阻塞并挂起虚拟线程,思路与此一致。
线程切换 vs 进程切换
- 是:同进程内的线程切换只需保存/恢复少量寄存器和栈指针;进程切换还须切换地址空间(换页表基址寄存器、TLB 全部失效)。
- 不是:不同进程的线程之间切换,本质上仍是进程切换,开销并不小。
- 易混:线程”轻”的全部来源就是不换页表、TLB 不失效。
2.2.1 调度的概念
高级调度(作业调度)
- 是:从外存后备队列中挑选作业调入内存,为其建立 PCB,使之成为进程进入就绪队列。
- 不是:调度程序本身是常驻的,被创建的是被选中的作业,不是调度程序自己。
- 易混:每个作业只被调入一次、调出一次,这与低级调度的反复选中形成对照。
- 范围:主要存在于批处理系统。分时、实时系统通常直接建立进程,无后备作业队列。
中级调度(内存调度)
- 是:把暂时不能运行的进程换出到外存(进入挂起态),条件合适时再换回内存,以提高内存利用率和系统吞吐量。
- 不是:换出时PCB 仍留在内存,只有程序和数据被换到外存——否则 OS 无从知道它的存在。
- 易混:对应状态转换是”就绪↔静止就绪""阻塞↔静止阻塞”。
- 范围:仅存在于采用了对换/虚拟存储技术的系统。
低级调度(进程调度)
- 是:从就绪队列中选一个进程,把 CPU 分配给它。频率最高(毫秒级)。
- 不是:不创建也不撤销进程,只在已有的 PCB 之间做选择。
- 易混:↔ 高级调度(后者”无中生有”地创建 PCB)。
- 范围:是唯一必不可少的调度层级,任何多道程序系统都必须有。选择题问”哪种调度必不可少”,答案恒为进程调度。
分时系统
- 是:把 CPU 时间划分成很短的时间片轮流分配给各联机用户作业,使每个用户都感觉独占整台机器。四特征为多路性、独立性、及时性、交互性。
- 不是:不追求平均周转时间最短,核心追求是响应时间短。
- 易混:因此通常采用时间片轮转(RR)——只有 RR 能保证响应时间有上界。
实时系统
- 是:要求在规定时限(deadline)内完成对外部事件的响应。分硬实时(绝对不能超时)与软实时(允许偶尔超时)。
- 不是:不以平均性能为评价标准,在乎的是最坏情况。
- 易混:通常采用抢占式优先级调度——紧急任务必须能立刻剥夺 CPU。
2.2.2 调度的实现
调度程序的三部分
- 是:排队器(把就绪进程排成队列)、分派器(取出 PCB,把 CPU 交给选中进程)、上下文切换器(执行两次上下文切换)。
- 不是:三者不是并列的算法,而是把”换人”拆成决策准备与执行两个环节。
- 易混:调度是决策(选谁),分派是执行(怎么换过去)。考题问的是哪一环节要看清。
不能进行调度的三种情况
- 是:① 处理中断的过程中;② 进程处于操作系统内核程序临界区中;③ **原子操作(原语)**执行过程中。
- 不是:普通临界区是可以调度的,不要与内核程序临界区混为一谈。
- 易混:三条的理由各不相同——中断处理中系统状态不完整;内核临界区锁住核心数据结构会导致系统卡死;原语本就处于关中断状态。
内核程序临界区 vs 普通临界区
- 是:内核程序临界区访问内核数据结构(就绪队列、PCB 链表、内存分配表);普通临界区访问普通临界资源(打印机、共享文件)。
- 不是:只有内核程序临界区禁止调度。普通临界区不但可以调度,而且应该允许——否则 CPU 要陪着占用打印机的进程一起空等。
- 易混:判据是被锁住的是内核自己的数据结构,还是外部资源。
剥夺式 vs 非剥夺式
- 是:非剥夺(非抢占)只有当前进程主动让出才重新调度;剥夺(抢占)允许更紧迫的进程立即夺走 CPU。
- 不是:抢占不是随意的,须遵循优先权原则、短作业优先原则或时间片原则。
- 范围:分时系统与实时系统必须采用抢占式,否则响应时间和截止时间无法保证。
闲逛进程 (idle)
- 是:就绪队列为空时运行的进程。优先级最低,不需要 CPU 之外的任何资源因而永不阻塞,执行能耗低的指令(如
HLT)。 - 不是:不是空转的死循环。
HLT让 CPU 进入低功耗停机状态、停止取指,直到中断到来才唤醒。因此”CPU 一直满负荷工作”这一前提本身不成立。 - 易混:统计”运行态进程数”时,闲逛进程通常不计入用户进程——这正是运行态可以是 0 个的由来。
上下文切换
- 是:保存当前进程的现场并恢复新进程的现场。开销主要来自切换页表基址寄存器导致的 TLB 全部失效。
- 不是:只能在内核态完成。权限上要读写 PCB、改页表基址寄存器(特权操作);逻辑上决策依据是内核数据结构,用户态看不见。
- 易混:调度 ≠ 切换。调度的结果可能仍是原进程,此时不发生切换。
处理机亲和性 (Affinity)
- 是:让进程尽量始终在同一处理机上运行,以保留该核 Cache 与 TLB 中已有的数据。软亲和性可迁移,硬亲和性可指定 CPU 子集。
- 不是:不是为了公平或负载均衡,恰恰相反——它与负载均衡是一对权衡。
- 范围:多处理机调度在 408 中属低频考点,一般只考概念辨析,不涉及复杂计算。
2.2.3 调度的目标
周转时间
- 是:
完成时间 − 提交时间。包含四段:外存等待作业调度 + 内存等待进程调度 + CPU 执行 + 等待 I/O 完成。 - 不是:不等于运行时间,恒 ≥ 运行时间。
- 易混:↔ 响应时间。周转时间的终点是”完成”,响应时间的终点是”首次响应”。
带权周转时间
- 是:
周转时间 / 实际运行时间。用于消除作业长短差异,反映用户的相对等待感受。 - 不是:恒 ≥ 1。算出小于 1 必定出错——这是最好用的自检点。
- 易混:设立它的理由是周转时间的绝对值对短作业不公平:等同样久,短作业的体验差得多。
等待时间
- 是:
周转时间 − 实际运行时间,即等待处理机的时间之和。 - 不是:不包含等待 I/O 的时间——进程做 I/O 时是在被设备服务,调度算法对此无能为力。
- 范围:口径随对象而变。对进程指等待处理机的时间;对作业还须加上在外存后备队列上等待作业调度的时间。
响应时间
- 是:
首次产生响应的时刻 − 提交请求的时刻。 - 不是:终点是首次响应,不是完成。一个作业可能 1ms 就有首次响应,却要 10s 才跑完。
- 易混:这是交互式/分时系统最看重的指标,也是分时系统采用 RR 的直接原因。
系统吞吐量 / CPU 利用率
- 是:吞吐量 =
完成作业数 / 总时间;CPU 利用率 =有效工作时间 / 总时间。 - 不是:吞吐量高不等于每个作业都快——长作业多则吞吐量低。
- 易混:各指标互相冲突,不存在全面最优的算法。选算法的实质是决定牺牲哪一项。
2.2.4 进程切换
进程切换的三步
- 是:① 保存原进程上下文(现场写回 PCB)② 更新 PCB 并转移队列 ③ 恢复新进程上下文并切换地址空间。
- 不是:开销的大头不是保存寄存器,而是切换页表基址寄存器导致的 TLB 全部失效与 Cache 命中率骤降。
- 易混:这正是线程”轻”的原因——同进程内线程切换不换地址空间,上述间接开销全部避免。
- 范围:进程切换只能在内核态完成。权限上要读写 PCB、改页表基址寄存器;逻辑上决策依据是内核数据结构。故进程切换必然伴随模式切换,反之不成立。
调度 vs 切换
- 是:调度是决策(按算法选出下一个进程);切换是执行(保存旧现场、恢复新现场)。先有调度,后有切换。
- 不是:“发生了调度”不等于”发生了切换”——调度的结果可能仍是原进程(如时间片到但无更合适者),此时一次切换都不做。
- 易混:↔ 上下文切换。上下文切换是那个具体动作;进程切换是整件事,还含更新 PCB、转移队列、切换地址空间。上下文切换器会执行两次上下文切换。
2.2.5 CPU 调度算法
FCFS 先来先服务
- 是:按到达先后排队,非抢占。最公平、实现最简单。
- 不是:不会导致饥饿(排队就一定轮得到),但对短作业极不友好。
- 易混:↔ 护航效应。其平均带权周转时间通常很大。
护航效应 (Convoy Effect)
- 是:FCFS 下一个长作业排在队首,后面所有短作业被迫陪等的现象。
- 不是:不是饥饿。护航只是”等得久”,最终仍会执行;饥饿是”可能永远轮不到”。
- 易混:后果集中体现在短作业的带权周转时间畸高上。
SJF 短作业优先 / SPF 短进程优先
- 是:每次选运行时间最短的,非抢占。属贪心算法,最优性可由交换论证严格证明。
- 不是:会导致饥饿——短作业不断到来则长作业永远排不上,极端情况下饿死。
- 范围:“平均周转时间最短”仅在①所有作业同时到达 ②非抢占 两个前提下成立。 到达时间不同时,最优者是 SRTN。这是本章最常被抽掉限定条件的结论。
SRTN 最短剩余时间优先
- 是:SJF 的抢占版本,比较剩余运行时间。到达时间不同的一般情形下平均周转时间最小。
- 不是:饥饿倾向比 SJF 更严重,且有抢占带来的切换开销。
- 易混:手算时决策点多了”新进程到达”一类,最易遗漏。
HRRN 高响应比优先
- 是:非抢占,选响应比最高者。响应比
。 - 不是:不会产生饥饿——等待时间增长会推高响应比,长作业最终必被选中。这是它相对 SJF 的核心优势。
- 易混:它是 FCFS 与 SJF 的折中:等待时间相同则短作业优先,服务时间相同则先来者优先。
RR 时间片轮转
- 是:按到达顺序排队,每进程运行一个时间片,用完即被剥夺并排到队尾。抢占式,分时系统标配。
- 不是:不会饥饿。n 个进程、时间片 q,则任一进程最多等待
。 - 易混:时间片过大退化为 FCFS;过小则切换开销占比过高。一般要求切换开销不超过 1%。
- 范围:RR 的结果依赖初始队列顺序。题目未给时按到达顺序;同时到达按题目列出顺序。另需约定:时间片用完与新进程到达同时发生时,新到达者先入队。
优先级调度
- 是:选优先级最高者,抢占与非抢占均可。静态优先级创建后不变,动态优先级可随等待时间提升。
- 不是:静态优先级会导致饥饿;动态优先级可缓解。
- 易混:优先级一般规律为——系统进程 > 用户进程;前台(交互)> 后台;I/O 型 > 计算型(让 I/O 型尽快让出 CPU,使设备与 CPU 并行)。
多级队列
- 是:设置多个就绪队列,不同队列采用不同调度算法,队列间有优先级。
- 不是:进程被固定分配到某队列,终生不能移动。
- 易混:↔ 多级反馈队列。区别就在能否移动。
多级反馈队列
- 是:多级队列的改进,进程可在队列间移动。优先级从高到低、时间片从小到大;新进程入第 1 级;时间片内未完成则降入下一级;仅当前
级全空才调度第 级;更高级队列有进程到达则立即抢占,被抢占者回原队列队尾。 - 不是:仍会产生饥饿——高优先级队列持续有进程则低级饿死。
- 易混:它无须预知作业长度即自动偏好短作业:短作业在前几级即完成;长作业逐级下沉但时间片变大,一旦轮到可连续执行。综合性能最好。
饥饿 (Starvation)
- 是:某进程因调度策略而长期(可能永远)得不到所需资源或 CPU。
- 不是:不是死锁。饥饿的进程在理论上仍可能被调度到,只是概率极低;死锁则是循环等待,绝无可能自行解除。
- 易混:只有 FCFS、HRRN、RR 三种算法不会饥饿。它们的共同点是决策依据含”等待时间”或有轮转保证。
2.2.6 多处理机调度
非对称多处理 AMP vs 对称多处理 SMP
- 是:AMP 指定一个主处理机负责所有调度决策,其余只执行用户代码;SMP 中每个处理机都可自我调度,地位平等。
- 不是:AMP 不需要考虑互斥(只有主处理机访问系统数据结构);SMP 必须解决互斥——这正是多处理器系统上自旋锁不可或缺的原因。
- 易混:SMP 是现代主流;AMP 的瓶颈在主处理机。
处理机亲和性 (Affinity)
- 是:让进程尽量始终在同一处理机上运行,以保留该核 Cache 与 TLB 中已有的内容。软亲和性可迁移,硬亲和性可指定 CPU 子集。
- 不是:不是为了公平。它的唯一理由是保留缓存局部性,而且它妨碍负载均衡。
- 易混:迁移的代价本质上就是一次”更彻底的” Cache/TLB 失效,与进程切换开销同源。
- 范围:亲和性与负载均衡互相冲突——前者要求尽量不迁移,后者要求哪里空往哪迁。实际系统靠负载差异阈值折中。亲和性保单个进程的效率,负载均衡保整体资源利用率。
负载均衡
- 是:设法让各处理机工作量大致均等。推迁移由专门任务周期性检查后把进程推给空闲核;拉迁移由空闲核主动拉取。
- 不是:共用一个就绪队列天然负载均衡,但队列本身成为临界资源、争用严重;每核私有队列无争用,但需额外的均衡机制。
- 范围:多处理机调度在 408 中属低频考点,一般只考概念辨析,不涉及计算。
2.3 同步与互斥
同步 (Synchronization)
- 是:多个进程为完成同一任务而协作,因而在执行次序上有确定的先后要求。又称直接制约关系。
- 不是:不是”同时发生”。中文的”同步”在这里指协调次序,不是 simultaneity。
- 易混:↔ 互斥。同步是”必须按序”,互斥是”不能同时”。
- 范围:互斥可视为同步的特例——它只要求不重叠,不要求谁先谁后。反之不成立。
互斥 (Mutual Exclusion)
- 是:多个进程因共享同一临界资源而互相排斥,同一时刻只允许一个进程访问。又称间接制约关系。
- 不是:进程之间本无关系,制约是通过资源间接传递的,故称”间接”。
- 易混:↔ 同步(直接制约,源于协作需求)。
临界资源 (Critical Resource)
- 是:一段时间内只允许一个进程访问的资源,如打印机、共享变量。
- 不是:不是”稀缺资源”。判据是能否被同时访问,与数量多少无关。
- 易混:↔ 共享。互斥共享的资源就是临界资源;同时共享的资源(只读文件、可重入代码)不是。
临界区 (Critical Section)
- 是:访问临界资源的那段代码。
- 不是:临界区是代码,临界资源是资源。 不同进程访问同一临界资源的代码段是不同的临界区,但必须互斥执行。
- 易混:进程访问临界资源的完整结构为进入区 → 临界区 → 退出区 → 剩余区,其中进入区与退出区由同步机制提供,另两段是进程自己的业务代码。
- 范围:本节讨论的是普通临界区(允许调度)。内核程序临界区规则相反,禁止调度。
同步机制四准则
- 是:① 空闲让进(空闲时应允许进入)② 忙则等待(有人在内则须等待)③ 有限等待(有限时间内能进入)④ 让权等待(进不去就释放 CPU)。
- 不是:四条分量并不相同。违反②是致命错误(互斥失效、结果出错);违反①③是功能缺陷(低效或饥饿);违反④只是性能问题(忙等浪费 CPU,功能仍正确)。
- 易混:正因为④只是性能问题,几乎所有硬件方法和自旋锁都违反④却仍被广泛使用。
单标志法
- 是:设公用变量
turn指示允许进入者,进程退出时把turn交给对方。 - 不是:违反”空闲让进”。两进程必须严格交替进入;若一方不再进入,另一方即使面对空闲临界区也永远进不去。
- 易混:它把”互斥”做成了”轮流”,管得太死。
双标志先检查法
- 是:
while(flag[j]); flag[i]=true;—— 先检查对方,再设置自己。 - 不是:违反”忙则等待”,是四个软件算法中唯一会导致互斥失效的,最严重。
- 易混:病根在于**“检查”与”上锁”之间可被中断**,两进程可同时通过检查。这正是硬件指令(TS、Swap)要把二者合并为原子操作的全部理由。
双标志后检查法
- 是:
flag[i]=true; while(flag[j]);—— 先设置自己,再检查对方。 - 不是:互斥实现了,但违反”空闲让进”和”有限等待”——双方几乎同时置位则互相谦让,谁也进不去。
- 易混:教材称此现象为”饥饿”,但两进程始终在忙等循环中未曾阻塞,严格说属于活锁,与死锁不同。
Peterson 算法
- 是:
flag[i]=true; turn=j; while(flag[j] && turn==j);—— 既表明意愿又主动谦让。 - 不是:只违反”让权等待”(仍是忙等),其余三条准则全部满足。
- 易混:能打破僵局的原因是
turn的最终值唯一——两进程抢着赋值,最后写入的那个决定谁等待,故必有且仅有一方通过。 - 范围:其正确性依赖内存访问的顺序一致性。现代 CPU 存在指令重排与写缓冲,实际使用必须插入内存屏障。此点超出考纲。
中断屏蔽法
- 是:
关中断; 临界区; 开中断;。与原语的实现手段相同。 - 不是:不能给用户进程使用——开/关中断是特权指令;若允许用户关中断后不再打开,整个系统即死。
- 范围:只适用于单处理机。关中断只关本 CPU,另一 CPU 上的进程照样能进临界区。且临界区必须很短。
TestAndSet (TS/TSL) 与 Swap (XCHG)
- 是:两条硬件原子指令。TS 一步完成”读出旧值 + 置为 true”;Swap 一步交换两变量的值。逻辑等价。
- 不是:不保证”有限等待”——多进程抢锁时无排队机制,谁抢到看运气,理论上可能一直抢不到。
- 易混:二者都违反让权等待(忙等)。它们的意义在于把”检查+上锁”在硬件层面合成一步。
互斥锁 (Mutex Lock)
- 是:提供互斥的锁,
acquire()进入前上锁,release()退出后解锁。二者必须是原子操作,故通常用硬件机制实现。 - 不是:教材所描述的实现(
while(!available);)即自旋锁,主要缺点是忙等待。教材前文”会被阻塞”一语中的”阻塞”是”被挡住”的宽泛用法,不是进程状态意义上的阻塞态。 - 易混:自旋锁 ⊂ 互斥锁。“互斥锁”只规定目的(提供互斥),不规定等不到时如何等待;自旋与阻塞是两种实现选择。
- 范围:优点是无上下文切换,因此适用于多处理器 + 短临界区。 单处理机上自旋是纯浪费——持锁者此刻根本没在运行。
自旋锁 (Spin Lock)
- 是:等不到锁时原地循环检查、不让出 CPU 的互斥锁。
- 不是:持有自旋锁期间不能进行调度。否则其他 CPU 上的等待者会空转整个时间片;同 CPU 上更可能直接死锁(新调度上来者若也要这把锁,将永远等不到已被换下的持有者)。
- 易混:实际系统中
spin_lock()内部会关闭内核抢占,必要时一并关中断。这与内核程序临界区禁止调度是同一件事。 - 范围:只需一条硬件原子指令即可实现,内核态和用户态都能用,不是操作系统专属机制。
整型信号量 vs 记录型信号量
- 是:整型信号量只是一个整数,
P用while(S<=0);忙等;记录型信号量增加等待队列,P减完为负时调用block()自我阻塞。 - 不是:只有记录型信号量满足让权等待。 教材后续所有题目默认使用记录型。
- 易混:整型信号量的值不会为负(卡在 0);记录型可以为负。
信号量 (Semaphore)
- 是:
value(剩余资源数)+ 等待队列。P:value--,若<0则阻塞;V:value++,若≤0则唤醒一个。 - 不是:
P不一定阻塞(减完 ≥0 则直接通过);V不一定唤醒(加完 >0 说明无人等待);V绝不会阻塞执行者。 - 易混:
value > 0表示尚余该数量的资源;value = 0表示刚好分完;value < 0时|value|即等待队列中的进程数(高频计算题)。 - 范围:互斥用法初值 1、P/V 在同一进程内夹住临界区;同步用法初值 0、P/V 分处两个进程、遵循**“前 V 后 P”**;前驱关系每条边一个信号量、初值全 0。
P/V 操作的顺序纪律
- 是:同步信号量的 P 必须在互斥信号量的 P 之前。即先确认资源到位,再进临界区。
- 不是:若先
P(mutex)再P(empty),进程会抱着互斥锁进入阻塞,对方永远拿不到锁去腾资源,死锁。 - 易混:两个 V 的顺序可以交换,不会死锁——V 永不阻塞执行者。只有 P 的顺序是致命的。
管程 (Monitor)
- 是:由局部共享数据结构、操作这些数据的一组过程、初始化语句和管程名组成的语言构造。三大特征:① 局部数据只能被管程内过程访问 ② 进程只能通过调用管程内过程进入 ③ 每次仅允许一个进程在管程内执行。
- 不是:管程是语法范围,不是执行实体,不会被创建和撤销——把它当成进程来理解就会读不懂相关命题。它是被动的,只有进程调用时其代码才执行。
- 易混:第③条的互斥由编译器自动保证,程序员无须编写任何进入区/退出区代码。这是管程相对信号量的全部优势。
- 范围:管程需要编程语言与编译器的支持;信号量由操作系统提供,任何语言均可使用。
条件变量 (Condition Variable)
- 是:管程内用于同步的变量,
x.wait()使调用者阻塞并释放管程使用权,x.signal()唤醒一个在x上等待的进程。 - 不是:
x.wait()若不释放管程使用权,就会把整个管程锁死——别人进不来,也就永远无法满足它等待的条件。 - 易混:一个管程内可以有多个条件变量,分别对应不同的等待原因。
signal 与 V 的区别
- 是:
V总是执行value++,即使无人等待也被记录下来,将来的P可直接通过——有记忆。 - 不是:
x.signal()若此刻无人在x上等待,什么也不做,信号直接丢失——无记忆。 - 易混:形象说法是”
V是存钱,signal是当面喊一嗓子”。因此管程的wait必须由条件驱动,不能依赖信号计数。
Hoare 语义 vs Mesa 语义
- 是:
signal之后由谁运行的两种约定。Hoare:唤醒者立即阻塞,被唤醒者马上运行;Mesa:唤醒者继续运行,被唤醒者仅转为就绪。 - 不是:Mesa 语义下被唤醒者真正运行时条件可能已不成立(中途可能被第三者抢走资源)。
- 范围:Mesa 语义下
wait必须写在while循环里,不能用if;Hoare 语义才可用if。Java 采用 Mesa 语义,这正是”wait()必须放在while中”这条铁律的根源。
生产者-消费者问题
- 是:
mutex=1(互斥访问缓冲区)、empty=n(空位数)、full=0(产品数)。任何时刻empty + full ≤ n。 - 不是:两个 P 不可换序(先同步后互斥);生产与消费动作必须放在临界区之外,否则无谓延长互斥时间。
- 易混:两个 V 的顺序可以交换。
首尾负责制
- 是:读者-写者问题的核心技巧——只有第一个到达者执行
P,只有最后一个离开者执行V,中间的同类直接进出。 - 不是:读者-写者中的
mutex保护的是计数变量count,不是文件;保护文件的是rw。 - 范围:该技巧有两种镜像用法——读者用它对内共享(让同类并发),写者用它对外封锁(把异类挡在门外)。
读者优先 / 读写公平 / 写者优先
- 是:三个版本的区别在于谁能插队。读者优先:读者绕过
rw直接count++,写者饿死;读写公平:新增闸门w,谁也不能插队;写者优先:写者群体用rd封锁读者入口,读者饿死。 - 不是:读写公平不等于写者优先——它只保证不饿死、先到先服务,并未给写者更高优先级。
- 易混:公平版的关键在
V(w)的放置位置:写者写完才V(w)(故等待期间一直堵着读者),读者登记完即V(w)(故读者之间仍可并发)。
哲学家进餐问题
- 是:5 人 5 筷,需同时持有左右两根才能进餐。若 5 人同时拿起左筷则形成循环等待,全体死锁。
- 不是:三种解法分别是——① 至多允许 4 人同时取筷(5 根分给 4 人必有一人能拿满两根)② 奇偶分流(奇数先左、偶数先右,相邻两人争同一根,必有一人失败让出)③ 用
mutex把”取两根”变成原子操作(不出现人人各持一根的中间状态)。 - 易混:这是 死锁的经典模型,三种解法各自破坏了不同的死锁必要条件。
2.4 死锁
死锁 (Deadlock)
- 是:多个进程各自占有一部分资源,同时又在等待其他进程占有的资源,导致全部无法向前推进的僵局。
- 不是:不是饥饿——死锁进程等的是永远不会被释放的资源,绝无可能自行解除;饥饿进程等的资源会被释放,只是每次轮不到它。也不是死循环——死循环是单个进程的逻辑 bug,进程仍在运行态占用 CPU,不属于操作系统问题。
- 易混:死锁至少涉及 2 个进程且都处于阻塞态;死循环 1 个进程即可且处于运行态。
- 范围:只有对不可剥夺资源的竞争才可能死锁。 对 CPU、主存等可剥夺资源的竞争不会引起死锁,因为它们随时能被收回再分配。
死锁产生的四个必要条件
- 是:① 互斥(资源一次只能给一个进程)② 不可剥夺(别人抢不走)③ 请求并保持(自己不放手)④ 循环等待(存在环形等待链)。
- 不是:它们是必要条件——死锁发生则四条必然全部成立。因此破坏任意一条即可保证不死锁,这正是死锁预防的全部思路。
- 易混:④单独看不是充分条件(见下条)。
不可剥夺条件 vs 请求并保持条件
- 是:不可剥夺是”别人抢不走”(外部视角,描述平时);请求并保持是”自己不放手”(自身视角,描述因新请求而阻塞时)。
- 不是:二者虽都表现为”资源留在持有者手中”,但描述的是不同时刻——前者说的是正常使用期间,后者说的是已经卡住却仍占着不放。
- 易混:破坏方法因此完全不同——破坏不可剥夺是申请失败即释放已有全部资源;破坏请求并保持是一次性申请全部资源(静态分配)。
循环等待条件
- 是:存在进程-资源的环形链,链中每个进程都在等待下一个进程占有的资源。
- 不是:有环不等于死锁。 每类资源有多个实例时,图上画得出环,系统却可能因为尚有空闲实例而未死锁。
- 范围:每类资源只有 1 个实例时,有环 ⟺ 死锁;有多个实例时,有环只是必要不充分条件。 这正是死锁检测必须用”化简”而非”找环”的原因。
可剥夺资源 vs 不可剥夺资源
- 是:可剥夺资源能被操作系统随时收回再分配(CPU、主存);不可剥夺资源必须由持有者用完后主动释放(打印机、磁带机)。
- 不是:对可剥夺资源的竞争不会产生死锁——环随时能被打破。
- 易混:CPU 靠时间片轮转收回,主存靠对换换出,二者都不具备构成死锁的资格。
鸵鸟策略
- 是:假装死锁不存在,发生了也不处理。
- 不是:不是疏忽,而是经过权衡的工程选择——通用系统中死锁概率极低,预防与避免的常态代价高于偶尔重启的代价。
- 易混:Linux、Windows 等通用操作系统实际采用的正是这一策略。
死锁预防
- 是:事前策略,在系统设计阶段破坏四个必要条件之一,使死锁从原理上不可能发生。
- 不是:不做运行时判断,是静态的”立法”。
- 易混:↔ 死锁避免(动态的”每次执法时现算”)。
- 范围:破坏”互斥条件”通常不可行——多数资源的互斥性由物理属性决定。SPOOLing 是少数可行的例子。
静态分配(预先分配)
- 是:破坏”请求并保持”的方法——进程运行前一次性申请全部所需资源,配不齐就不投入运行,运行期间不再提新请求。
- 不是:优点是简单安全,但资源浪费严重(最后才用的资源从一开始就被独占),且可能导致饥饿(需求种类多的进程难等到所有资源同时空闲)。
顺序资源分配法
- 是:破坏”循环等待”的方法——给资源编号,规定必须按编号递增顺序申请,同类资源一次申请完。
- 不是:不能保证进程不用等待,只保证等待关系不成环。若多个进程都在等同一个最大编号资源,那是普通等待或饥饿,不是死锁。
- 易混:无环的证明——若存在环则得
,矛盾。 - 范围:缺点是编号难以变更(不便增加新设备)、实际使用顺序与编号不符会造成浪费、给编程带来麻烦。
死锁避免
- 是:事中策略,每次分配前动态判断该分配是否会使系统进入不安全状态,安全才分配。代表算法是银行家算法。
- 不是:不预设规则,是动态判断,比预防灵活、资源利用率更高。
- 范围:进程可能长时间阻塞——它等的不是资源本身(资源可能正空闲着),而是算法的放行。因为算法按最大需求评估风险,会系统性高估危险。
安全状态 / 不安全状态 / 安全序列
- 是:若能找出至少一个执行顺序(安全序列),使各进程能一个接一个地拿够资源、跑完、归还,则系统处于安全状态;找不出任何一个即为不安全状态。
- 不是:安全序列不要求所有进程同时能被满足,只要求能接力推进。
- 易混:安全 ⟹ 一定不死锁;不安全 ⇏ 一定死锁(进程未必真的把最大需求全提出来)。死锁状态 ⊂ 不安全状态。
银行家算法
- 是:进程提出请求时,系统先做试探性分配,再执行安全性算法检查是否存在安全序列;存在则正式分配,不存在则回滚试探分配并让进程等待。
- 不是:答题时”试探性分配""安全序列""安全/不安全状态”三个词不可省略,否则表述不完整。
- 易混:四张表满足
Need = Max − Allocation;安全性算法中归还的是Allocation(实际占有量)而非Need,这是手算最常见的错处。 - 范围:几乎无通用操作系统采用——须预知最大需求(现实中做不到)、进程与资源数动态变化、开销约
、且过于保守。数据库改用检测+回滚。
同类资源不死锁的条件
- 是:
个进程共享 个同类资源、每个进程最多需 个时,不死锁的条件是各进程最大需求量之和 。 - 不是:不必死记公式。回到最坏情况即可推出——人人都拿到
个、都只差 1 个、且一个空闲都不剩时死锁,故只需保证 ,整理即得。 - 易混:验证法——
时 不成立,确实死锁; 时 成立,剩 1 个即可启动接力。
死锁检测
- 是:事后策略,允许死锁发生,通过资源分配图化简周期性判定,发现后再解除。
- 不是:限制最宽松、资源利用率最高,但需承担检测开销与解除代价。
- 易混:检测时机可以是”每次请求得不到满足时""定时""资源利用率骤降时”。
资源分配图
- 是:圆圈为进程结点,方框为资源结点(框内圆点数 = 该类资源的实例数)。请求边
P → R(进程正在申请),分配边R → P(已分配给该进程)。 - 不是:两种边方向相反,不可混淆。
- 易混:记忆抓手——箭头从谁指出,谁就是主动方:进程主动申请,资源被动地被分配出去。
资源分配图化简
- 是:反复找出”请求都能被当前空闲实例满足”的进程,假设其运行完毕并消去它的全部边,直到无法继续。全部结点变孤立则可完全简化。
- 不是:判断能否消去时,比较的是请求量与当前空闲实例数(总数减已分配),不是与总数比较。
- 易混:“环是嫌疑,化简才是定罪。” 不能只靠找环判定死锁。
死锁定理
- 是:S 为死锁状态的充分必要条件是——S 状态的资源分配图不可完全简化。
- 不是:它是一条判定准则,因此属于检测死锁的方法,不是预防、避免或解除。
- 易混:这个名字之所以陌生,是因为教材通常把重点放在”资源分配图化简”这个操作上;死锁定理只是给该操作的结论起的名字。会化简即掌握了死锁定理。
死锁解除的三种方法
- 是:资源剥夺法(挂起某些死锁进程并抢占其资源)、撤销进程法(强制撤销部分或全部死锁进程)、进程回退法(回退到检查点重新执行)。
- 不是:撤销进程法代价最大但实现最简单;进程回退法代价最小但实现最复杂——代价与复杂度恰好相反。
- 易混:资源剥夺法须防止被挂起进程长期饥饿。选择牺牲品应综合考虑优先级、已运行时间、剩余时间、已占资源、进程类型。
附:本章高频”范围限定”清单
考试最爱在这些结论上抽掉限定条件:
| 结论 | 成立范围 |
|---|---|
| 运行态进程至多 1 个 | 仅单处理机 |
| 就绪队列最多 n−1 个 | 仅单处理机,n 为进程总数 |
| 不能并行 | 仅单核 / 多对一模型 / 用户级线程 |
| 线程是调度的基本单位 | 仅内核级线程 |
| 进程是调度的基本单位 | 仅未引入线程时 |
| 同步互斥由 OS 自动完成 | 仅管道,共享存储须进程自理 |
| 一个线程阻塞则全进程阻塞 | 仅用户级线程 / 多对一模型 |
| 进程有层次结构 | 仅 UNIX/Linux,Windows 无 |
| 匿名管道可用 | 仅有亲缘关系的进程 |
| 作业的概念 | 主要用于批处理系统 |
| 高级调度存在 | 主要用于批处理系统 |
| 中级调度存在 | 仅采用对换/虚拟存储的系统 |
| SJF 平均周转时间最短 | 仅”同时到达 + 非抢占” |
| 等待时间含外存排队 | 仅对作业,对进程不含 |
| 必须抢占式调度 | 仅分时、实时系统 |
| 禁止调度 | 仅内核程序临界区,普通临界区可调度 |
| 上下文切换 | 仅内核态可执行 |
| 流水公式 | 仅各作业各级耗时相同、每级一台设备 |
| 违反准则只是性能问题 | 仅”让权等待”;违反”忙则等待”是致命的 |
| 中断屏蔽法可用 | 仅单处理机、仅内核态 |
| Peterson 算法正确 | 仅顺序一致性内存模型,现代 CPU 需内存屏障 |
| 自旋锁划算 | 仅多处理器 + 短临界区 |
| 持锁期间禁止调度 | 仅自旋锁(阻塞型互斥锁本就会让出 CPU) |
可省掉 mutex | 仅缓冲区容量为 1 时 |
wait 可用 if | 仅 Hoare 语义;Mesa 语义必须用 while |
| 竞争会导致死锁 | 仅不可剥夺资源;CPU、主存不会 |
| 有环 ⟺ 死锁 | 仅每类资源 1 个实例时;多实例时有环未必死锁 |
| 顺序分配法保证的 | 仅”无循环等待”,不保证不用等待 |
| 安全 ⟹ 不死锁 | 成立;但不安全 ⇏ 死锁 |
银行家算法看 Need | 化简看当前请求边,两者依据不同 |
链接
- 🏠 返回总览:操作系统第 2 章:进程与线程总览
- 📜 原始提问档案:第 2 章 原始提问档案(本地资料)
- 📖 附录总入口:操作系统附录