
咱们直接进入正题。每当提到 408 计算机学科专业基础综合很多同学第一反应是数据结构“代码难写”、计算机网络“协议太碎”、计算机组成原理“硬件看不懂”但真正到考场上最容易出现“看着眼熟、选不对、大题写不满”的往往是操作系统。操作系统在 408 中占 35 分左右包含 10 道左右选择题和 2 道左右大题。它的难度不在于某个算法有多深而在于知识点极其分散并且喜欢把内存管理、文件管理、设备管理混在一起考查。更麻烦的是操作系统很多概念必须结合“真实系统”来理解否则你背了调度算法、页面置换算法仍然做不对综合题。这篇文章准备围绕 408 考纲中的操作系统主线完整梳理一遍核心知识点包括进程与线程、处理机调度、同步与互斥、死锁、内存管理、虚拟内存、文件管理、设备管理与 I/O 软件层次以及在真实环境中最常见的 Linux 操作验证方式。无论你是刚开始复习的第一轮还是已经进入刷题阶段都可以把本文作为一份“考点地图”对照着查缺补漏。1. 操作系统在 408 中的定位与考纲主线1.1 为什么操作系统复习容易出错先看一个问题为什么很多同学操作系统选择题错得多原因是操作系统这门课具有“双重属性”一部分是策略与算法例如进程调度、页面置换、磁盘调度另一部分是机制与实现例如系统调用、中断处理、地址翻译过程、目录结构。408 试卷上选择题往往考概念辨析和机制理解大题则喜欢考综合计算。比如给你一个请求分页系统问你页表项大小、缺页中断处理流程、页面置换次数这一串问题其实串联了内存管理、文件管理、中断机制多个模块。所以复习操作系统不能只看“结论”必须能讲清楚“某个机制发生时的完整过程”。1.2 408 操作系统考纲核心模块408 操作系统部分大致分为以下六个主题主题核心内容常考题型进程管理进程/线程、调度、同步、死锁选择 大题内存管理连续分配、分页、分段、虚拟内存选择 大题文件管理文件逻辑结构、目录、磁盘块管理选择 大题输入输出管理I/O 控制方式、缓冲、SPOOLing、磁盘调度选择 大题系统调用与操作系统接口系统调用流程、库函数与系统调用关系选择为主虚拟机与容器、多处理器等新兴概念虚拟机监控器、容器与虚拟机区别选择为主这个顺序也基本是大多数教材和课程推荐的复习顺序因为进程管理是贯穿后续所有章节的基础。1.3 复习操作系统时最容易忽略的一个点很多同学会忽略“操作系统与硬件的关系”。例如缺页中断是如何产生的地址翻译需要哪些硬件寄存器DMA 传输过程中 CPU 参与了多少。这部分其实是把计算机组成原理和操作系统联系起来的桥梁。408 是统考不会严格区分“这是计组的题还是操作系统的题”所以复习时要有意识地做跨科目联想。2. 进程与线程操作系统的地基2.1 进程的定义与进程控制块进程是资源分配的基本单位也是处理机调度的基本单位严格说线程才是处理机调度的基本单位。每当创建一个进程操作系统就要为它建立进程控制块PCBProcess Control Block。PCB 是进程存在的唯一标志里面记录了进程标识符、处理机状态通用寄存器、程序计数器等、进程调度信息状态、优先级等、内存管理信息、I/O 状态信息等。可以这样理解如果把进程比作一个“正在运行的程序实例”PCB 就是这个程序实例在操作系统内部的“身份证和档案”。上面这个定义很多书都有但是 408 常考的细节是进程实体 程序段 相关数据段 PCB。进程与程序的区别进程是动态的程序是静态的进程可并发执行程序不能。进程的创建、撤销、状态转换都涉及对 PCB 的操作。2.2 进程的状态与转换经典的三态模型是运行态、就绪态、阻塞态。408 考试中可能还会扩展到创建态和终止态。需要记住的关键点就绪态 → 运行态处理机被分配。运行态 → 就绪态时间片用完或被更高优先级进程抢占。运行态 → 阻塞态等待某事件如 I/O 完成。阻塞态 → 就绪态所等待的事件发生。最容易混淆的一个进程从运行态变成阻塞态是“主动等待”从运行态变成就绪态是“被动让出”。而阻塞态不能直接变成运行态必须先变为就绪态再由调度程序选择。2.3 进程和线程的区别线程是处理机调度的基本单位进程是资源分配的基本单位。同一个进程内的多个线程共享进程的地址空间、打开的文件等资源但每个线程有自己的程序计数器、寄存器和栈。从 408 考试角度看重点掌握线程切换比进程切换开销小因为线程切换不涉及地址空间切换。进程是资源拥有者线程不拥有系统资源但可以使用所属进程的资源。引入线程后同一个进程内的线程之间并发不再需要进程切换。2.4 处理机调度算法对比调度算法是选择题绝对高频。下面用一张表把常见算法整理清楚调度算法核心思路优点缺点适用场景FCFS 先来先服务按到达时间排队公平、实现简单对短作业不友好可能产生护航效应批处理系统SJF 短作业优先选择预计运行时间最短的作业平均等待时间最短需要预估运行时间可能饥饿批处理系统优先级调度按优先级高低调度可区分紧急任务低优先级进程可能饥饿实时系统、交互系统RR 时间片轮转按时间片轮流执行响应快、公平时间片大小影响性能分时系统多级反馈队列多个队列优先级递减时间片递增兼顾响应时间和吞吐量实现复杂通用操作系统这里有一个高频计算题型给定一组进程的到达时间和运行时间计算平均等待时间、平均周转时间、带权周转时间。这种题必须亲手算不能只看不练。2.5 经典调度题示例下面给出一道简单的调度计算题大家可以用它检查自己的掌握程度。假设系统中有三个进程 A、B、C到达时间均为 0运行时间分别为 5、2、3采用 SJF 调度需要计算平均等待时间。按照短作业优先执行顺序为 B2、C3、A5。所以B 的等待时间 0C 的等待时间 2A 的等待时间 2 3 5平均等待时间 (0 2 5) / 3 7 / 3 ≈ 2.33。如果采用 FCFS按照到达顺序 A、B、C 执行那么A 的等待时间 0B 的等待时间 5C 的等待时间 5 2 7平均等待时间 (0 5 7) / 3 4。可以看到SJF 在这组数据下明显优于 FCFS。这类题在 408 中属于送分题前提是你对每种算法的执行顺序非常熟悉。2.6 进程同步与互斥进程同步的核心问题是多个进程需要访问临界资源时如何保证互斥并避免死锁和饥饿。临界资源是指一次只允许一个进程使用的资源例如打印机、共享变量。每个进程访问临界资源的过程可以分为四个部分进入区检查是否能进入临界区。临界区访问临界资源。退出区释放资源。剩余区其余代码。实现互斥的软件方法有 Peterson 算法硬件方法有中断屏蔽、TestAndSet 指令、Swap 指令。408 更常考的是信号量机制。2.7 信号量与 PV 操作信号量是一个整数变量P 操作wait或 down表示申请资源V 操作signal或 up表示释放资源。在408中通常写成P(S) { S.value S.value - 1; if (S.value 0) { 将当前进程插入等待队列; 阻塞该进程; } } V(S) { S.value S.value 1; if (S.value 0) { 唤醒一个在等待队列中的进程; } }这里的 S.value 如果为正数表示当前可用资源数如果为负数其绝对值表示等待队列中的进程数。用信号量实现互斥的经典结构semaphore mutex 1; P(mutex); // 进入临界区 // 访问共享资源 // 退出临界区 V(mutex);生产者-消费者问题、读者-写者问题、哲学家就餐问题是 408 大题的常客。建议至少亲手写一遍生产者-消费者问题的 PV 操作并且能解释为什么缓冲池满时生产者要阻塞、为什么两个信号量的 P 操作顺序不能颠倒。2.8 死锁死锁产生的四个必要条件必须背熟互斥条件资源一次只能被一个进程使用。请求并保持条件进程持有资源又申请新的资源。不可剥夺条件进程持有的资源不能被强制剥夺。循环等待条件存在一个进程等待环。预防死锁就是破坏这四个条件中的任意一个避免死锁通常在资源分配时用银行家算法判断系统是否处于安全状态而检测和解除死锁则是通过资源分配图来判断。408 对死锁的考查经常结合银行家算法。题型通常是这样给出系统资源总数、每个进程的最大需求、当前已分配资源和剩余资源然后问你当某个进程请求资源时系统是否应分配。解题步骤是检查请求是否不超过最大需求。检查请求是否不超过当前可用资源。试探性分配资源。执行安全性算法检查是否存在安全序列。安全序列不唯一只要能找到一条就说明系统处于安全状态可以分配。3. 内存管理从连续分配到虚拟内存3.1 内存管理的核心问题内存管理要解决四个问题内存空间的分配与回收。地址转换逻辑地址到物理地址的转换。内存空间的扩充通过虚拟内存。内存共享与保护。在 408 中地址转换过程最常结合计算机组成原理中的页表、快表TLB一起考。3.2 连续分配管理方式连续分配包括单一连续分配、固定分区分配、动态分区分配。动态分区分配有几种常见算法首次适应按地址从低到高找到第一个满足大小的大块。最佳适应按容量从小到大找到能满足要求的最小块。最坏适应按容量从大到小找到最大块。邻近适应从上一次分配位置继续查找。其中首次适应性能最好最常考。这里要注意最佳适应虽然名字听起来好但会产生大量难以利用的外部碎片。3.3 分页存储管理分页存储管理的基本思想是将内存空间划分为大小相等的块页框或物理块将进程的逻辑地址空间也划分为同样大小的页。进程的页可以离散地装入到内存中任意空闲的物理块。逻辑地址结构为页号 页内偏移量。如果页面大小为 4KB2^12页内偏移量就是 12 位。例如逻辑地址 8192十进制页面大小 4KB那么页号 8192 / 4096 2页内偏移量 8192 % 4096 0。页表的作用是把页号映射到物理块号。地址转换过程如下根据逻辑地址拆出页号和页内偏移量。用页号去页表中查找对应的物理块号。物理地址 物理块号 × 页面大小 页内偏移量。页表项通常包含物理块号和状态位、访问字段、修改位等。注意页表项大小不是固定 4B 或 8B需要根据题目给出的条件计算。3.4 快表 TLB 的作用使用页表访问一个逻辑地址需要两次访问内存第一次查页表第二次访存。如果引入快表 TLBTranslation Lookaside Buffer那么先访问 TLB如果命中则只需要一次访问内存。假设 TLB 命中率为 98%访问 TLB 需要 20ns访问内存需要 100ns。那么有效访问时间大约为EAT 0.98 × (20 100) 0.02 × (20 100 100) 0.98 × 120 0.02 × 220 117.6 4.4 122ns这种计算题在 408 选择题中反复出现公式本身不难关键是理解未命中时要额外多一次内存访问来查页表。3.5 分段存储管理与段页式分段存储管理按程序的逻辑结构代码段、数据段、栈段等划分每个段是独立的逻辑单元。逻辑地址结构为段号 段内偏移量。分页是系统管理的需要对用户不可见分段是用户编程的需要对用户可见。分页的页面大小固定分段的段长不固定。段页式管理则是先分段再对每段分页。逻辑地址结构为段号 页号 页内偏移量。地址转换需要三次访问内存查段表、查页表、访存所以段页式在实际系统中需要引入快表提高效率。3.6 虚拟内存与局部性原理虚拟内存基于局部性原理程序在一段时间内访问的代码和数据往往集中在某个区域。因此程序的部分装入内存即可运行其余部分在需要时再换入。虚拟内存的实现方式有三种请求分页存储管理。请求分段存储管理。请求段页式存储管理。重点在请求分页。3.7 页面置换算法当需要调入新页面但内存已满时需要选择换出哪个页面。常见算法包括OPT 最佳置换选择以后永不使用或最长时间不再访问的页面淘汰。理论最优无法实现但作为性能上限。FIFO 先进先出淘汰最早进入内存的页面。实现简单但可能产生 Belady 异常分配物理块数增加时缺页次数反而增加。LRU 最近最久未使用选择最近一段时间内最久没有访问的页面淘汰。性能较好但需要硬件支持寄存器或栈。Clock 时钟置换每次选择访问位为 0 的页面淘汰访问位为 1 则置 0 并继续查找。下面给一个简单的 LRU 手算示例页面访问序列为 7, 0, 1, 2, 0, 3, 0, 4分配给进程的物理块数为 3初始内存为空。访问页内存块1内存块2内存块3是否缺页77缺页070缺页1701缺页2201缺页淘汰70201命中3231缺页淘汰00230缺页淘汰14430缺页淘汰2缺页次数为 7 次缺页率 7 / 8 87.5%。这种手算过程看起来简单但一旦序列变长、物理块变多很容易出错。建议在草稿纸上维护一个“最近使用顺序”列表每次访问后更新。3.8 请求分页中的缺页中断与地址变换请求分页模式下页表项会新增状态位是否在内存、访问字段、修改位、外存地址等。逻辑地址访问流程变为根据逻辑地址拆出页号和页内偏移量。在快表中查找页号如果命中且有效位为 1直接得到物理块号。如果快表未命中访问页表。如果页表项状态位无效产生缺页中断从外存调入页面并更新页表和快表。重新执行访问指令。缺页中断与普通中断的区别是缺页中断在指令执行期间产生并且执行完缺页中断处理后可能重新执行被中断的指令这是 408 一个隐蔽考点。4. 文件管理从逻辑结构到磁盘空间分配4.1 文件与文件系统文件是以计算机硬盘为存储介质的信息集合。文件系统负责文件的存储、检索、共享和保护。文件的逻辑结构分为无结构文件如文本文件是一系列字节流。有结构文件如数据库文件由一组相似记录组成可分为顺序文件、索引文件、索引顺序文件。4.2 目录结构文件目录由目录项组成。目录结构包括单级目录实现简单但查找慢且不能重名。两级目录分为主文件目录和用户文件目录不同用户可以有同名文件。多级目录树形目录现代操作系统最常使用支持按名存取、方便分类管理。树形目录是目前最常见的形式。路径名分为绝对路径和相对路径。绝对路径从根目录开始相对路径从当前目录开始。408 中考查路径计算时注意“当前目录”的概念不能混淆。4.3 文件的物理分配方式文件在磁盘上如何存放常见方式有三种分配方式思想优点缺点连续分配文件占一组连续磁盘块顺序访问和随机访问性能好实现简单产生外部碎片文件扩展困难链接分配隐式链接每个磁盘块通过指针指向下一个块消除外部碎片可动态扩展只能顺序访问指针占用空间任一指针损坏影响后续索引分配为每个文件建立索引块存储所有磁盘块号支持随机访问无外部碎片索引块本身占用空间大文件需要多级索引在 408 大题中索引分配是最常考的。题目会给出索引块大小、盘块大小、地址长度要求计算最大文件大小。假设盘块大小为 4KB磁盘地址为 4B一个索引块可以存放 4KB / 4B 1024 个地址。如果使用单级索引最大文件大小为 1024 × 4KB 4MB。如果是两级索引最大文件大小为 1024 × 1024 × 4KB 4GB。这类题必须会算。4.4 空闲存储空间的管理空闲空间管理方法包括空闲表法记录每个连续空闲区的大小和位置。空闲链表法将所有空闲块链接成链表。位示图法用二进制位表示每个磁盘块是否空闲1 表示已分配0 表示空闲。成组链接法用分组的方式管理大量空闲块适用于大型文件系统。位示图法是 408 的高频考点。如果盘块总数是 N每个字长 W 位那么位示图所需字数 N / W向上取整。此外还会考给定盘块号计算在位示图中的行号和列号。4.5 磁盘调度算法磁盘调度影响的是磁盘 I/O 的时间属于设备管理部分但经常和文件管理结合起来考。常见算法包括FCFS按请求到达顺序服务最公平但效率低。SSTF 最短寻道时间优先优先服务离当前磁道最近的请求可能饥饿。SCAN 电梯算法磁头沿一个方向移动服务沿途请求直到尽头再反向。C-SCAN 循环扫描磁头只沿一个方向服务返程不服务。下面来看一个典型的 SCAN 计算题。假设当前磁头在 100 磁道向磁道号增加的方向移动请求队列为 55, 58, 39, 18, 90, 160, 150, 38, 184。SCAN 算法先向增加方向移动按顺序访问 150, 160, 184然后反向访问 90, 58, 55, 39, 38, 18。移动的总磁道数为(184 - 100) (184 - 18) 84 166 250如果题目没有说明磁头方向则默认从当前磁道按顺序方向移动。判断方向需要根据题目条件仔细阅读。5. 输入输出管理设备控制器、中断与 DMA5.1 I/O 控制方式处理器如何控制与外部设备的交互常见方式有四种控制方式特点CPU 参与程度程序直接控制方式CPU 循环检测设备状态CPU 全程参与浪费资源中断驱动方式设备完成后主动发中断CPU 在中断后介入但每次传输一个字DMA 方式通过 DMA 控制器直接访问内存一次传输一块数据CPU 仅在传输开始时设置参数、结束时处理中断通道控制方式通道独立执行 I/O 指令序列CPU 基本不参与数据传输DMA 与中断方式的对比经常考DMA 传输以数据块为单位中断方式以字为单位DMA 在传输完成后才向 CPU 发中断中断方式在每次数据准备完成后都发中断。5.2 缓冲区与 SPOOLing缓冲区的作用是缓和 CPU 与 I/O 设备速度不匹配的矛盾减少对 CPU 的中断频率。缓冲技术有单缓冲、双缓冲、循环缓冲、缓冲池。SPOOLing 技术把独占设备改造为共享设备。典型实例是打印机系统当多个进程请求打印时SPOOLing 系统将这些请求放入磁盘上的打印队列输出进程依次处理使打印机看起来可以“同时”被多个进程使用。SPOOLing 需要输入井和输出井磁盘上开辟的空间、输入缓冲区和输出缓冲区。5.3 I/O 软件层次I/O 软件自上而下分为用户层软件库函数如 printf、scanf。设备独立性软件向用户提供统一接口负责设备分配、缓冲区管理。设备驱动程序与具体硬件交互将抽象 I/O 请求转换为具体的寄存器操作。中断处理程序处理 I/O 中断。硬件设备机械部件和电子部件。408 常考的一个问题是设备分配时应使用逻辑设备名还是物理设备名答案是在设备独立性软件层用户使用逻辑设备名设备分配时将逻辑设备名映射为物理设备名。6. 系统调用、虚拟机与操作系统演进6.1 系统调用是什么系统调用是操作系统提供给应用程序的编程接口是用户程序请求内核服务的唯一合法方式。应用程序通过库函数如 printf间接执行系统调用如 write。系统调用的执行过程包括用户程序将系统调用号和参数放入寄存器。执行陷入指令trap 或 int 指令从用户态切换到内核态。内核根据系统调用号查找系统调用表执行相应服务例程。返回结果从内核态切换回用户态。判断一道选择题系统调用发生在用户态执行系统调用时进入内核态“陷入指令”本身是特权指令吗不是。陷入指令是一条“用户态执行、但能触发模式切换”的指令这是常见的陷阱选项。6.2 虚拟机与容器虚拟机通过虚拟机监控器Hypervisor/VMM在一台物理机上模拟多台虚拟机每台虚拟机运行独立操作系统。虚拟机分为两种类型Type 1 裸机型VMM 直接运行在硬件上例如 KVM、VMware ESXi。Type 2 宿主型VMM 运行在宿主操作系统之上例如 VirtualBox、VMware Workstation。容器与虚拟机的区别在于容器与宿主机共享操作系统内核只隔离用户空间因此比虚拟机更轻量。常见容器如 Docker。408 对这块的考查偏概念重点在于区分“共享内核”和“独立内核”。这一点也可以解释很多同学的困惑比如在某个系统上制作了一个程序放到另一个操作系统上却无法运行提示“不是此操作系统平台的有效应用程序”。这往往不是因为程序坏了而是因为可执行文件的格式和依赖的系统调用接口不同。这个问题放到操作系统原理里本质就是不同的操作系统具有不同的可执行文件格式、系统调用指令和 ABI 约定。6.3 Linux 与国产操作系统在 408 之外的实践意义从考试角度408 不会直接考 Linux 命令但很多学校复试、机试以及实际工程场景会涉及 Linux 操作系统。近年来国产操作系统如麒麟、统信 UOS在信创领域的使用场景越来越常见它们大多基于 Linux 内核所以掌握 Linux 基础命令对理解操作系统概念有直接帮助。例如在 Linux 中查看进程状态ps -aux top查看内存信息free -h查看磁盘分区df -h这些命令不是 408 考点但如果你在校实验课上接触过这些命令对“进程状态、内存管理、设备管理”的理解会明显更具体。特别是学习内存管理和进程调度时打开top看到S列的值R 运行、S 睡眠、D 不可中断睡眠、Z 僵尸比死记教材上的状态图更有效。7. 408 真题风格与高分解题策略7.1 选择题常见套路操作系统选择题喜欢在下面几个点上设置干扰项“进程是处理机调度的基本单位”还是“线程是处理机调度的基本单位”。要重点关注题干说的是“资源分配”还是“处理机调度”。程序与进程的区别例如“程序是动态的”这种错误表述。分页和分段的混淆“分页对用户不可见、分段对用户可见。”系统调用性质“系统调用发生在用户态”和“系统调用在内核态执行”并不矛盾。页面置换算法的 Belady 异常是否可能发生FIFO 会LRU 和 OPT 不会。磁盘调度算法中“电梯算法”到底是 SCAN 还是 C-SCAN 的别名。7.2 大题答题规范操作系统大题很多是“计算 过程描述”型。答题时建议按以下步骤明确列出已知条件。写出关键公式或原理。给出计算过程不要只写最终答案。对涉及策略的题目简要说明理由。例如银行家算法的题就需要把 Available、Need、Allocation 三个矩阵列清楚然后一步步做安全性检查。7.3 经典计算题题型大家复习时可以把操作系统大题归纳为以下题型调度算法计算平均等待时间、平均周转时间。PV 操作实现进程同步。银行家算法判断安全性。分页/分段地址转换。页面置换算法求缺页次数。索引分配求最大文件大小。磁盘调度算法求寻道距离。磁盘地址计算柱面、磁头、扇区。把这些题型每一种都练熟操作系统 35 分基本可以稳定到 30 分左右。8. 常见误区与排除思路8.1 常见理解误区误区正解认为分页和分段是一回事分页是系统管理需要分段是用户编程需要认为死锁避免就是死锁预防预防是破坏四个必要条件避免是银行家算法认为 LRU 不会产生缺页LRU 只是减少缺页次数不是消除缺页认为 DMA 传输不需要 CPU 干预DMA 启动和结束仍需要 CPU只是数据搬运不经过 CPU认为系统调用在用户态执行系统调用“发出”在用户态“执行”在内核态认为线程切换一定比进程切换快同一进程内线程切换确实快但不同进程的线程切换同样需要地址空间切换8.2 复习排错思路如果你在练习题时同一个知识点反复错建议按下图顺序排查先看概念定义是否准确记忆。再看算法流程能否完整叙述。再看计算题步骤是否按标准流程书写。最后对照真题答案找出自己的表述差异在哪里。不要一开始就刷大量新题操作系统知识点之间联系很紧密基础概念错了后面所有综合题都会受影响。9. 复习规划与资料选择建议9.1 三轮复习法第一轮以教材和课程为主建立知识框架。重点看书上的概念、流程图、状态转换图并配合少量选择题巩固。第二轮以题型训练为主把上面的 8 类大题逐一攻克。这一轮应该把每种题型的解题步骤固定下来形成自己的模板。第三轮以真题为主限时完成整卷。操作系统需要与其他三门科目搭配保持手感即可不需要大量偏题怪题。9.2 资料选择408 操作系统复习资料不需要太多核心是教材 真题 一本习题集。教材方面常见的有汤子瀛《计算机操作系统》和近年各机构使用的统考复习教材。真题一定要吃透近十年因为 408 的出题风格稳定很多考点会重复考查。9.3 时间分配建议如果按照 408 四科平均分配复习时间操作系统大约占四分之一。但操作系统大题计算量大、记忆点多建议在第二轮复习时专门预留时间集中突破。对于在职考生或时间紧张的同学可以优先掌握进程调度、PV 操作、银行家算法、地址转换、页面置换、磁盘调度、索引分配这几块它们是 408 大题的绝对核心。10. 最后一个建议动手写一遍 PV 操作很多同学觉得 PV 操作难不是因为不会写代码而是因为没有真正理解“阻塞”和“唤醒”的过程。这里给出一份经典的生产者-消费者问题核心代码建议你亲手写一遍而不是只做选择题。// 生产者-消费者问题核心逻辑类 C 伪代码 semaphore mutex 1; // 保护缓冲池互斥访问 semaphore empty n; // 空缓冲区数量初始为 n semaphore full 0; // 装满数据的缓冲区数量 // 生产者 producer() { while (1) { // 生产数据 P(empty); // 申请一个空缓冲区 P(mutex); // 进入临界区 // 将数据放入缓冲区 V(mutex); // 退出临界区 V(full); // 满缓冲区数量加 1 } } // 消费者 consumer() { while (1) { P(full); // 申请一个满缓冲区 P(mutex); // 进入临界区 // 从缓冲区取出数据 V(mutex); // 退出临界区 V(empty); // 空缓冲区数量加 1 // 消费数据 } }注意P(empty) 和 P(mutex) 这两个操作的顺序不能随意交换。如果先 P(mutex) 再 P(empty)当缓冲池为空时消费者拿到了 mutex 却因为没有数据而阻塞这会导致生产者也无法进入临界区最终造成死锁。类似这种“顺序错误导致死锁”的例子在同步问题里非常多值得自己动手画一画资源分配情况。这篇梳理没有把操作系统所有细枝末节都列出来而是把 408 高频考点按主线过了一遍。如果你正在备考建议边看边在纸上画状态转换图、地址转换流程和调度执行序列然后立刻找对应真题练手。操作系统是 408 里投入产出比最高的一门课把上述知识框架吃透分数一定不会差。