简介:这是一份面向计算机专业本科生的操作系统期末复习笔记,聚焦核心概念梳理与考点精讲,帮助学生高效应对考试。笔记系统覆盖操作系统目标(方便性、有效性、可扩充性、开放性)、发展历程(人工操作→批处理→分时→实时系统)、四大基本特性(并发性、共享性、虚拟性、异步性),以及处理机、存储器、设备和文件四大管理功能;重点详解进程状态转换、PCB结构、进程同步机制(信号量P/V操作、整型/记录型/AND型/信号量集)、经典同步互斥问题(生产者-消费者、哲学家进餐)及管程思想。资源为1个1.17MB的Word文档(.docx),内容排版清晰、术语准确、逻辑连贯,适合作为考前速记与知识脉络梳理工具。目前已有779人学习下载,内容源自一线学习实践,知识点与高校主流教材(如汤小丹《计算机操作系统》)高度契合,便于对照理解、查漏补缺与强化记忆。
1. 操作系统期末复习:一张不能跳过的知识地图——并发、虚拟、调度、死锁、I/O,五座大山必须逐个翻越
操作系统不是一堆零散概念的堆砌,而是一套严密咬合的“资源控制逻辑链”:从程序如何被装进内存(装入与链接),到它怎样争抢CPU(调度与同步),再到它用完资源后如何被换出(对换与置换),最后连打印一个文件都要绕过物理限制(SPOOLing与缓冲)——所有环节都由四个基本特性贯穿始终:并发是前提,共享是手段,虚拟是扩展方式,异步是运行常态。这张地图里没有“可选模块”,只有“必经关卡”。比如,不理解进程状态转换(就绪→执行→阻塞→挂起),就无法看懂为什么分时系统能“同时”响应多个用户;不厘清页表+快表+缺页中断三者协作机制,就永远算不准一次内存访问的真实耗时(EAT);而若跳过信号量集和AND型信号量的设计动机,面对多资源请求场景时,你写的同步代码大概率在考试现场当场死锁。这份笔记不是按教材章节目录平铺直叙,而是按“期末高频失分点”重新组织:把分散在四章里的调度算法(FCFS/SJF/HRRN/RR/PSA)拉到一起对比参数含义与适用场景;把穿插在存储管理各节的“地址变换流程”浓缩成一张带命中/未命中分支的决策树;把死锁预防、避免、检测三类策略的触发时机和代价差异列成表格——让你复习时一眼看清“考什么、怎么考、哪里最容易翻车”。适合两类人:一类是刚学完课、脑中还飘着碎片化术语的本科生,需要一张能串起全书的骨架图;另一类是刷过几套真题、发现总在“银行家算法安全序列判定”或“LRU/Clock置换结果差异”上栽跟头的冲刺者,需要直击命题陷阱的拆解指南。
2.1 并发与进程:状态转换不是画图游戏,PCB才是真正的“进程身份证”
进程不是静态代码,而是动态实体——它的生命体征全靠进程控制块(PCB)实时记录。很多同学背熟了“就绪、执行、阻塞”三态图,却在题目里看到“创建态”“终止态”“挂起态”就懵了,本质是没抓住PCB的演化逻辑:PCB的诞生即进程的诞生,PCB的销毁即进程的死亡,而所有状态转换,都是操作系统对PCB中特定字段的修改。
- PCB核心字段解析(必须能默写其作用):
进程标识符:全局唯一ID,不是PID数字本身,而是操作系统定位该进程的“钥匙”;进程状态:直接决定调度器是否将其加入就绪队列(如状态=就绪)或是否触发阻塞唤醒(如状态=阻塞且等待事件发生);程序计数器(PC):记录下一条要执行的指令地址,进程切换的本质就是保存/恢复PC值;CPU寄存器集合:包括通用寄存器、状态寄存器等,确保进程被中断后能“无缝续播”;内存管理信息:页表基址、段表基址等,没有这些,进程连自己的代码在哪都不知道;I/O状态信息:打开文件列表、已分配设备等,防止进程误操作其他进程的资源。
提示:考试常考“进程切换时保存哪些内容?”答案不是笼统说“上下文”,而是精准指向PCB中的
PC、寄存器集合、状态字段。若题目问“为什么线程切换比进程切换快?”,核心答案就是:线程共享同一PCB的内存与I/O信息,只需切换各自的PC和寄存器集合,省去了页表/段表切换开销。
状态转换的底层驱动是原语(Primitive)。原语不是普通函数,而是由关中断/开中断指令封装的原子操作——执行中不可被中断。例如block()原语将进程置为阻塞态并插入等待队列,若执行到一半被中断,会导致PCB状态字段与实际队列位置不一致,整个系统可能崩溃。这也是为什么所有教材强调“原语必须一气呵成”。
2.2 进程同步:信号量不是万能胶,四种机制对应四类问题场景
同步的本质是用确定性规则约束不确定性行为。当多个进程并发访问临界资源(如打印机、共享缓冲区),若无协调,结果必然不可再现。但不同场景需匹配不同同步机制,生搬硬套P/V操作只会南辕北辙。
| 同步机制 | 适用场景 | 关键特征与致命缺陷 | 典型失分点 |
|---|---|---|---|
| 整型信号量 | 单资源互斥(如单台打印机) | 初值=1;wait()自减,signal()自增;存在忙等(Busy Waiting) | 题目若要求“避免CPU空转”,此方案直接判错 |
| 记录型信号量 | 单资源互斥+需阻塞等待 | 引入value和list(阻塞队列);wait()中value<0则入队;实现让权等待 | 易忽略list字段作用,误以为仅靠value就能阻塞 |
| AND型信号量 | 多资源一次性分配(如哲学家进餐需左右两筷) | Swait(S1,S2,...,Sn):全满足才分配,否则全部释放;彻底避免死锁 | 常混淆“一次性分配”与“顺序申请”,导致死锁分析错误 |
| 信号量集 | 多资源差异化分配(如某进程需3个R1+1个R2) | Swait(S1,t1,d1,...):t1为下限,d1为需求数;支持资源阈值控制 | 忽略t参数意义,误将“资源不足”等同于“完全不可用” |
注意:考试中出现“某进程需同时占用2个磁盘和1个打印机”,必须用信号量集(
Swait(disk,2,2, printer,1,1)),而非对三个信号量分别做P操作——后者可能造成死锁(进程占1磁盘+1打印机后,卡在第二个磁盘请求上)。
2.3 经典同步问题:生产者-消费者不是背代码,而是建模能力训练
这道题是期末卷的“压轴常客”,但90%的同学只记住了empty/full/mutex三个信号量和P/V顺序,却答不出“为什么mutex的P操作必须在empty/full之后?”。本质是建模思维缺失:你要把现实约束翻译成信号量语义。
empty:表示空缓冲区数量,初始值=n(缓冲区总数)。生产者每放1个产品,empty--;消费者每取1个,empty++。full:表示满缓冲区数量,初始值=0。生产者每放1个,full++;消费者每取1个,full--。mutex:保护缓冲区数组本身(临界资源),初始值=1。
关键逻辑链:
- 生产者必须先确认有空位(
wait(empty)),再加锁操作缓冲区(wait(mutex)),否则可能因缓冲区满而阻塞在加锁前,导致消费者永远无法取走产品; - 若先加锁再检查空位,一旦缓冲区满,生产者会一直持有锁阻塞,消费者因无法加锁而饿死——这就是“锁粒度不当”引发的活锁。
// 正确顺序:先验资源,再锁临界区 producer() { while(1) { item = produce_item(); wait(empty); // Step1: 确认有空位(资源检查) wait(mutex); // Step2: 加锁保护缓冲区(临界区进入) insert_item(item); signal(mutex); // Step3: 解锁 signal(full); // Step4: 通知消费者有新产品 } }2.4 管程:当信号量变得太复杂,就该请“管家”出场
管程(Monitor)是比信号量更高层的同步抽象,核心思想是把共享变量+所有操作封装成一个“黑匣子”,确保每次只有一个进程能进入执行。它解决的是信号量机制的两大痛点:
- 逻辑分散:P/V操作散落在各进程代码中,维护困难;
- 易出错:忘记P或V、P/V顺序颠倒、信号量初值设错,都会导致死锁或竞态。
管程内部包含:
- 共享变量(如缓冲区数组、
count计数器); - 条件变量(
notFull,notEmpty),用于进程等待/唤醒; - 入口队列:等待进入管程的进程队列;
- 条件队列:在条件变量上等待的进程队列(如
notFull.wait()使生产者挂起)。
易错点:条件变量的
wait()操作自动释放管程锁,而signal()只是唤醒等待者,不立即移交锁——被唤醒进程需重新竞争入口队列。这与信号量的signal()直接增加value有本质区别。考试若问“管程中signal()后进程是否立刻执行?”,答案必须是“否,需重新排队”。
3. 调度与死锁:算法不是数学公式,而是资源博弈的实时决策
调度算法的选择不是看谁名字高大上,而是看系统目标与资源瓶颈的匹配度。分时系统追求响应快,所以用时间片轮转(RR);批处理系统追求吞吐量,所以用短作业优先(SJF);而实时系统必须保证任务按时完成,所以用最早截止时间优先(EDF)或最低松弛度优先(LLF)。死锁更是如此——预防是“事前打疫苗”,避免是“事中做体检”,检测是“事后查病灶”,三者成本与效果天差地别。
3.1 调度算法实战对比:参数、公式、失分雷区全解析
所有调度算法的计算都围绕三个核心时间指标:
- 周转时间= 完成时间 - 到达时间(衡量作业总耗时)
- 等待时间= 周转时间 - 运行时间(衡量CPU空闲等待时长)
- 响应时间= 首次响应时间 - 到达时间(分时系统关键指标)
| 算法 | 触发时机 | 关键参数/规则 | 优点与致命缺陷 | 典型陷阱 |
|---|---|---|---|---|
| FCFS | 新进程到达 | 按到达顺序排队 | 公平、简单;平均等待时间长,短作业饥饿 | 忽略“非抢占式”特性,误认为可被新到长作业打断 |
| SJF | CPU空闲时 | 选择剩余运行时间最短的进程 | 平均等待时间最优;需预知运行时间,实际难实现 | 将“短作业优先”误解为“已运行时间短”,实为“剩余时间短” |
| HRRN | CPU空闲时 | 响应比=(等待时间+剩余时间)/剩余时间;选最大者 | 兼顾等待与运行时间;非抢占式,长作业不饥饿 | 计算响应比时漏加“剩余时间”,或混淆分子分母 |
| RR | 时间片结束 | 固定时间片q;超时则强制切换 | 响应快、公平;q过小则切换开销大,q过大退化FCFS | 画甘特图时忽略“时间片用尽但进程未完成”的切出动作 |
| PSA | 新进程到达/时间片结束 | 按优先级调度;可抢占/非抢占 | 紧急任务及时响应;优先级倒置风险 | 忽略“动态优先级”场景(如随等待时间升高),误用静态优先级 |
提示:计算HRRN时,必须用“剩余服务时间”而非“总服务时间”。例如作业A到达时间0,总服务时间8,已运行3,则剩余时间=5,若此时等待时间=2,则响应比=(2+5)/5=1.4。若误用总时间8,结果完全错误。
3.2 死锁:四个必要条件不是考点,而是破题的手术刀
“互斥、请求保持、不可抢占、循环等待”这四条,不是让你默写,而是提供一套死锁诊断工具。遇到题目描述“进程A占打印机等磁盘,进程B占磁盘等打印机”,立刻对应:
- 互斥:打印机、磁盘均为独占资源 → ✔
- 请求保持:A已占打印机,又申请磁盘;B已占磁盘,又申请打印机 → ✔
- 不可抢占:打印机/磁盘无法被强制剥夺 → ✔
- 循环等待:A→B→A形成环路 → ✔
→ 四条件齐备,必死锁。
银行家算法是避免死锁的核心,但学生常卡在“安全序列判定”上。关键步骤:
- 找出
Need[i] ≤ Work的进程i(Need=还需资源,Work=当前可用资源); - 将
Allocation[i](已分配给i的资源)加回Work,即Work = Work + Allocation[i]; - 标记进程
i完成,重复1-2直到所有进程完成(安全)或找不到满足条件的进程(不安全)。
易错点:
Work初始值是系统当前可用资源(Available),不是Max或Allocation之和!且每次Work更新后,必须用新Work值重新扫描所有未完成进程,不能只扫一遍。
3.3 死锁检测与解除:图论不是炫技,而是找“罪魁祸首”
死锁检测用资源分配图(Resource Allocation Graph):
- 圆圈代表进程,方框代表资源类型,方框内圆点代表资源实例;
- 进程→资源的有向边=请求边(虚线),资源→进程的有向边=分配边(实线);
- 图中存在环路 ⇔ 可能死锁(注意:仅当每类资源仅1个实例时,环路=必然死锁)。
解除死锁时,“终止进程”策略需权衡代价:
- 终止所有死锁进程:简单粗暴,但可能丢失大量工作;
- 逐个终止:按“代价最小”原则选择,如优先终止占用资源少、运行时间短、优先级低的进程。考试若问“应终止哪个进程?”,答案必须基于具体数据计算代价,而非主观猜测。
4. 存储管理:从物理地址到虚拟地址,一场关于“欺骗”的精密工程
存储管理的核心矛盾是:程序需要连续大内存,而物理内存碎片化且容量有限。解决方案是层层“欺骗”:装入时用重定位骗过地址依赖,分页时用页表骗过连续性要求,虚拟内存时用缺页中断骗过容量限制。所有技术都服务于一个目标——让进程相信自己独占一片广阔、连续、高速的内存空间。
4.1 装入与链接:静态重定位 vs 动态重定位,一字之差,天壤之别
| 类型 | 发生时机 | 如何修改地址 | 优缺点 | 期末高频考点 |
|---|---|---|---|---|
| 绝对装入 | 编译时 | 直接生成物理地址 | 简单;仅适用于单道程序,无重定位能力 | 基本不考,但需知其局限性 |
| 可重定位装入 | 装入时 | 将逻辑地址+起始地址→物理地址(静态重定位) | 支持多道程序;地址固定,无法移动 | 常考“为什么不能用于对换?”——因地址已固化,移动后所有地址失效 |
| 动态运行时装入 | 执行时 | 通过重定位寄存器(Base Register)动态计算:物理地址=Base+逻辑地址 | 支持对换、紧凑;地址可变,开销略大 | 必考“重定位寄存器作用?”——答案:存放程序在内存的起始地址 |
提示:动态重定位的硬件支持是重定位寄存器。当操作系统将进程换出再换入时,只需更新该寄存器的值,无需修改进程代码中的任何地址——这是实现对换(Swapping)的技术基础。
4.2 分页与分段:不是选择题,而是组合拳
分页(Paging)和分段(Segmentation)常被对比,但真实系统(如x86)是分页+分段混合使用。理解差异的关键在于:
- 分页是系统视角:把内存切成固定大小(如4KB)的“页框(Frame)”,程序切成同样大小的“页(Page)”,页表建立页号→页框号映射;
- 分段是用户视角:按逻辑功能(主程序、栈、堆、数据段)划分“段(Segment)”,段表建立段号→段基址+段长映射;
| 特性 | 分页 | 分段 | 混合(段页式) |
|---|---|---|---|
| 地址结构 | 一维:页号+页内偏移 | 二维:段号+段内偏移 | 三维:段号+页号+页内偏移 |
| 大小 | 固定(系统决定) | 可变(用户决定) | 段内分页,页大小固定 |
| 目的 | 解决外碎片,提高内存利用率 | 满足用户模块化需求,便于共享保护 | 兼顾两者优势,但地址变换更复杂(段表→页表→物理地址) |
易错点:分页的“页内偏移”与分段的“段内偏移”本质相同,都是相对于起始地址的偏移量。但分页的页号是纯数值索引,分段的段号需查段表获取基址——因此分段支持“段共享”(多个进程段表项指向同一段基址),分页不直接支持。
4.3 快表(TLB)与地址变换:两次访存不是性能瓶颈,而是设计必然
分页系统中,CPU给出逻辑地址,需经两次内存访问才能拿到数据:
- 访问页表,根据页号查出物理块号;
- 用物理块号+页内偏移,访问实际数据。
快表(TLB)是解决此问题的缓存:它是一个小容量、高速的联想存储器,存放最近用过的页表项(页号→物理块号)。地址变换流程:
- CPU发出逻辑地址 → 同时查TLB和页表;
- 若TLB命中(Hit):直接获得物理块号,1次访存;
- 若TLB未命中(Miss):查页表得物理块号,并将该页表项装入TLB,2次访存。
有效访问时间(EAT)计算公式:
EAT = (TLB访问时间 + 内存访问时间) × 命中率 + (TLB访问时间 + 页表访问时间 + 内存访问时间) × (1-命中率)注意:TLB访问时间极短(纳秒级),常被忽略,但公式中必须体现其存在。若题目给“TLB命中率90%,内存访问时间200ns,TLB访问时间10ns”,则EAT = (10+200)×0.9 + (10+200+200)×0.1 = 189 + 41 = 230ns。
5. 虚拟内存与页面置换:局部性原理不是玄学,而是所有优化的基石
虚拟内存不是魔法,它建立在局部性原理这一铁律之上:程序在一段时间内,只会活跃在地址空间的一小部分。这意味着:
- 时间局部性:刚访问的指令/数据,很快会被再次访问(如循环);
- 空间局部性:访问某个地址,其附近地址很可能也被访问(如数组遍历)。
页面置换算法的本质,就是预测未来哪些页最不可能被访问,从而腾出空间。但预测永远有误差,因此算法优劣取决于“缺页率”(Page Fault Rate)。
5.1 页面置换算法:从理想到现实的渐进式妥协
| 算法 | 核心思想 | 是否可实现 | 缺点与适用场景 | 考试关键点 |
|---|---|---|---|---|
| OPT(最佳) | 淘汰未来最久不使用的页 | ❌ 不可实现 | 理论最优,作为其他算法评价基准 | 必考“为什么不可实现?”——因无法预知未来访问序列 |
| FIFO | 淘汰最早调入的页(队列头) | ✅ | 可能淘汰常用页(Belady异常),性能差 | 常考“Belady异常”:增加页框数,缺页率反而上升 |
| LRU | 淘汰最近最久未使用的页(栈顶) | ⚠️ 近似实现 | 接近OPT,但硬件开销大(需时间戳或栈维护) | 必考“如何用栈模拟LRU?”——访问页时将其移到栈顶,淘汰栈底页 |
| Clock | 用访问位(R)标记页是否被使用,循环扫描淘汰R=0页 | ✅ | 比FIFO好,比LRU省硬件;改进型Clock加修改位(M)区分脏页 | 易错:忽略“R位清零”时机(每次扫描时清R,非访问时设R) |
提示:改进型Clock算法中,页被访问时R=1,被修改时M=1。置换时优先淘汰R=0&M=0页;若无,则淘汰R=0&M=1页(需写回外存);若全R=1,则清所有R位,再扫描一轮。考试若给访问序列,必须按此规则逐步推演。
5.2 请求分页与缺页中断:一次缺页,七步连锁反应
请求分页(Demand Paging)允许进程只装入部分页就启动,其余页在需要时再调入。当CPU访问的页不在内存时,触发缺页中断(Page Fault Interrupt),操作系统必须完成以下七步:
- 保护CPU现场(存PC、寄存器等);
- 查页表,确认该页在外存;
- 调用页面分配程序,选择空闲页框;
- 启动磁盘I/O,将所需页从外存读入空闲页框;
- 修改页表项:置
P=1(在内存),填入物理块号; - 若TLB中有该页表项,更新TLB;
- 恢复CPU现场,重新执行引发缺页的指令。
注意:第4步磁盘I/O是耗时大户(毫秒级),远超内存访问(纳秒级)。因此降低缺页率是虚拟内存性能的核心。而局部性原理正是所有优化(如预取、工作集模型)的理论依据。
6. I/O管理与设备驱动:从轮询到通道,CPU的“甩手掌柜”进化史
I/O管理的目标是解放CPU,让它专注计算,而非等待设备。技术演进路径清晰:轮询(CPU傻等)→ 中断(CPU干别的,设备喊我)→ DMA(CPU只管块,DMA管字节)→ 通道(CPU只管作业,通道管所有I/O)。每一步都在扩大CPU的“自由时间”。
6.1 I/O控制方式:四代技术,本质是责任转移
| 方式 | CPU参与程度 | 数据传输单位 | 典型场景 | 期末辨析点 |
|---|---|---|---|---|
| 程序I/O(轮询) | CPU全程监控设备状态,忙等 | 字节/字 | 早期简单设备,效率最低 | 必考“为什么效率低?”——CPU 99%时间在空转查状态 |
| 中断驱动I/O | CPU发指令后去干别的,设备就绪后发中断通知 | 字节/字 | 键盘、鼠标等低速设备 | 易错:认为中断后CPU立即处理,实则需保存现场+查中断向量表 |
| DMA | CPU初始化DMA控制器后不管,DMA自主完成块传输 | 数据块(如1KB) | 磁盘、网卡等高速设备 | 必考“DMA与CPU是否并行?”——是,DMA传输时CPU可继续计算 |
| I/O通道 | CPU只发通道程序(Channel Program),通道独立执行所有I/O操作 | 一组I/O操作(如读10块) | 大型机,最高级,接近独立处理器 | 常考“通道与DMA区别?”——通道可执行复杂指令(寻址、跳转),DMA只能简单传送 |
6.2 SPOOLing技术:把独占设备变成“云打印机”
SPOOLing(Simultaneous Peripheral Operations On-Line)是虚拟设备技术的典范,它用磁盘作缓冲,将慢速独占设备(如打印机)虚拟成多个快速共享设备。其四部分协同工作:
- 输入井/输出井:磁盘上的大文件,分别暂存待输入/输出的数据;
- 输入缓冲区/输出缓冲区:内存中的小缓冲区,缓解CPU与磁盘速度差;
- 输入进程/输出进程:常驻内存的守护进程,负责在设备与井之间搬运数据;
- 井管理程序:接收用户I/O请求,为其在井中分配空间并登记。
易错点:SPOOLing的“脱机”是逻辑脱机,非物理脱机。用户进程不直接操作打印机,而是与“假脱机管理进程”交互,后者再调度输出进程完成真实打印。考试若问“SPOOLing如何实现设备共享?”,答案必须包含“井管理程序为每个用户建立独立假脱机文件”这一关键步骤。
6.3 缓冲技术:单缓冲、双缓冲、循环缓冲,不是数量游戏,而是节奏匹配
缓冲的核心是平衡生产者与消费者的速度差。
- 单缓冲:1个缓冲区,生产者填满→消费者取空→生产者再填。效率低,存在空闲期;
- 双缓冲:2个缓冲区交替使用,生产者填Buffer A时,消费者取Buffer B。消除空闲期,但需同步(如用信号量
empty/full); - 循环缓冲(环形缓冲区):N个缓冲区首尾相连,用
in/out指针管理。适合流式数据(如音频),但需处理指针追尾(in==out为空,(in+1)%N==out为满)。
提示:循环缓冲区判断满/空的经典方案是牺牲1个缓冲区:
if ((in+1)%N == out) full; if (in == out) empty;。考试若给N=8,当前in=3,out=5,则已用缓冲区数=(in-out+N)%N = (3-5+8)%8 = 6。
7. 期末查漏补缺:一份可执行的复习清单与我的血泪经验
复习操作系统,最怕陷入“看了全会,一做就废”的怪圈。从教过十几届学生的某导师反馈和历年真题分析看,85%的失分点集中在五个具体动作上:画不对状态转换图、算错银行家算法安全序列、混淆页式/段式地址结构、写错信号量P/V顺序、说不清TLB与页表协作流程。下面这份清单,是我用三年带教经验打磨出的“防翻车指南”,每一条都对应一个高频扣分场景,请逐项核对:
7.1 五维自查清单:对照真题,立刻定位薄弱点
| 维度 | 自查问题 | 达标标准(能独立完成) | 我的教训 |
|---|---|---|---|
| 状态转换 | 给出“创建→就绪→执行→阻塞→挂起→就绪”全过程,标出每个转换的触发事件(如“执行中I/O请求→阻塞”) | 能画出含5个状态+7条转换边的图,并准确写出10个以上触发条件(如“时间片到”“I/O完成”“等待事件发生”) | 曾因混淆“挂起”与“阻塞”,在考试中把“内存不足”导致的换出写成“I/O等待”,丢了6分。从此我强迫自己给每个状态贴标签:“阻塞=等事件,挂起=等内存”。 |
| 同步建模 | 面对“读者-写者问题(读者优先)”,能否写出readcount、mutex、wrt三个信号量及完整P/V代码? | 能写出无死锁、无饥饿的代码,并解释为何readcount初值=0、wrt初值=1、mutex初值=1;能指出读者优先的体现(readcount为0才P(wrt)) | 第一次写时,我把readcount的P/V放在了读操作内部,导致多个读者并发时readcount值错误。后来我记住口诀:“计数器操作必须原子,永远用mutex保护”。 |
| 调度计算 | 给定4个进程(到达时间、服务时间),能否手算FCFS/SJF/RR(q=4)/HRRN的甘特图、周转时间、平均等待时间? | 能在10分钟内完成所有算法计算,且RR甘特图精确到每个时间片(如P1运行4ms后切P2,P2运行3ms后P1剩余1ms继续) | 在模拟考中,我把RR的时间片q=4误解为“每个进程最多运行4ms”,实际是“每轮分配4ms”,导致甘特图整体偏移。现在我画RR图必先标时间轴:0,4,8,12...再填进程。 |
| 内存地址 | 给定逻辑地址0x1234、页面大小4KB、页表项[0:5, 1:10, 2:3],能否算出物理地址?TLB命中率90%时,EAT是多少?(内存200ns,TLB10ns) | 能分步写出:页号=0x1234/4096=1,页内偏移=0x1234%4096=0x234,物理块号=10,物理地址=10*4096+0x234;EAT=(10+200)*0.9+(10+200+200)*0.1 | 曾在页号计算中用十进制除法,忘了0x1234是十六进制,结果全错。现在我强制自己:所有地址运算前先转十进制,算完再转回。 |
| I/O流程 | 描述“用户打印请求→SPOOLing输出→真实打印机工作”的完整数据流向,标出每个环节的主体(进程/程序/硬件) | 能画出:用户进程→假脱机管理进程(建文件)→输出井(磁盘)→输出进程(读井)→输出缓冲区(内存)→打印机控制器→打印机。并指出“输出进程”是常驻内存的守护进程。 | 有次把“输出进程”写成“用户进程的一部分”,忽略了其独立性。后来我记牢:SPOOLing的四大组件中,两个进程(输入/输出)和一个管理程序(井管理)是OS内核级服务,与用户进程严格隔离。 |
7.2 三类易漏点:那些教材不写、老师不讲、但考试必考的细节
- “挂起态”的双重身份:挂起态(Suspended)不是独立状态,而是就绪/阻塞态的“休眠版”。
就绪挂起表示进程具备运行条件但被换出内存;阻塞挂起表示进程在等事件且被换出。考试若问“挂起态进程能否被调度?”,答案必须是“不能,必须先激活(Activate)回到就绪/阻塞态”。 - 信号量初值的隐含语义:
mutex=1表示资源可用;empty=n表示n个空位;full=0表示无产品。初值不是随意设的,它直接定义了资源的初始状态。曾见真
本文还有配套的精品资源,点击获取