简介:这份资源是《操作系统精髓与设计原理》第八版课后习题的参考答案文档,面向正在学习操作系统课程的高校学生、考研复习者以及需要巩固理论基础的开发者,帮助解决进程管理、调度算法与并发编程等章节的习题难点。压缩包内共1个docx文件,约904KB,内容以文字解答与图示说明为主,覆盖状态转换图、进程调度策略、资源管理及并发程序分析等典型题型。文档对习题3.1至5.6等题目给出了详细推导,例如就绪、运行、阻塞与非常驻态之间的转换事件,以及中间调度策略如何平衡优先级与交换开销;并发部分还通过指令交替执行顺序,分析共享变量x打印“x is 10”与“x is 8”的时序,并讨论tally变量的上下界范围。目前已有7515人学习下载,适合作为课后对照与考前查漏补缺的参考材料。
1. 进程状态转换到底在讲什么:从一道课后题看懂操作系统的“调度大脑”
如果你翻过操作系统教材,大概率见过一张画着圆圈和箭头的图——就绪、运行、阻塞、挂起几个框,箭头来回指。很多人第一反应是“背下来就行”,结果考试一考“什么事件触发就绪到运行”,脑子就空了。其实这张图就是操作系统的调度大脑:它决定了CPU什么时候给谁用、谁该等着、谁该被暂时请出内存。拿“操作系统第八版习题答案”里的经典题来说,它问的就是每个箭头背后到底发生了什么事件。搞懂这套状态转换,你再看进程调度、资源管理、并发编程,会发现它们全是在这张图上做文章。这也是为什么“操作系统答案”和“习题答案”里,进程管理永远排在最前面——它是整门课的地基。
2. 为什么进程非得有这么多状态:从“做菜”理解就绪、运行和阻塞
2.1 一个厨房三个灶眼:状态存在的根本原因
打个比方。你家里只有一个灶眼,但有三道菜要做:一道正在炒,一道切好了等着下锅,一道还在解冻。正在炒的就是运行态,切好等着的是就绪态,解冻的就是阻塞态。灶眼只有一个,所以同一时刻只能有一道菜在炒——这就是单处理器系统里,运行态进程最多一个的原因。
那为什么不能把所有菜都堆在灶台边上?因为灶台面积有限,对应到计算机里就是内存有限。当内存里塞不下那么多进程时,操作系统就得把一些进程“请”到磁盘上暂存,这就是非常驻态,也叫挂起态。教材里那道题问“就绪态到非常驻态是什么事件引发的”,答案就是内存中进程已达上限,或者系统并发度需要降低。通俗地说,就是灶台放不下了,先把切好的菜放回冰箱。
理解了这个类比,你就明白状态转换不是人为规定的,而是资源限制逼出来的。处理器只有一个,内存只有那么大,磁盘虽然大但速度慢,操作系统必须在这些约束下做取舍。每一次状态转换,本质上都是操作系统在回答一个问题:现在这个进程,是该让它跑、让它等,还是让它先离开内存?
2.2 每个箭头背后的事件:把转换图翻译成人话
教材里那道题要求列出每个状态转换的引发事件,标准答案其实就六条。就绪到运行,是分派器选中了它,相当于厨师终于腾出锅来炒这道菜。运行到就绪,是被抢占了,比如时间片用完,或者更高优先级的进程来了,厨师被迫放下锅铲去处理更急的菜。运行到阻塞,是进程自己作死——它要读磁盘、要等I/O完成,就像炒菜炒到一半发现盐没了,只能停下来等买盐的人回来。
阻塞到就绪,是等待的事件发生了,盐买回来了,可以继续切菜等着下锅。就绪到非常驻,是内存满了,系统把暂时轮不上的进程换到磁盘。阻塞到非常驻也类似,反正你都在等I/O了,内存又紧张,干脆先把你整个换出去。这六条转换里,只有运行到阻塞是进程主动的,其他都是操作系统根据资源和调度策略做的决定。
这里有个容易翻车的点:很多人以为阻塞态进程一旦等待的事件完成,就直接变成运行态。不对,它必须先回到就绪态,重新排队等分派器选中。就像盐买回来了,菜也不能立刻下锅,还得看灶眼空不空。这个细节在“操作系统第八版习题答案”的3.1题里是明确考到的,也是初学者最容易搞混的地方。
2.3 从时刻表看状态变化:3.2题为什么值得反复做
教材3.2题给了一串时刻和事件,让你判断每个进程在时刻22、37、47的状态。这种题看着像流水账,其实是在训练你把状态转换图和真实调度场景对应起来。比如时刻5,P1执行读磁盘命令,它就从运行态进入阻塞态,等待磁盘I/O完成。时刻15,P5时间片结束,从运行态回到就绪态。时刻28,换出P5,它就从就绪态或阻塞态进入非常驻态。
做这类题的关键是画一张表,横轴是进程,纵轴是时刻,每个事件发生后更新对应进程的状态。不要试图在脑子里同时跟踪五个进程,一定会乱。习题答案里给出的那种紧凑表格,其实就是这个思路的简化版。你如果正在学操作系统,建议把3.2题亲手画一遍表格,比看十遍答案都管用。这也是为什么“课后答案”不能只用来对答案,得用来复盘推导过程。
3. 调度策略里的两难:优先级和交换到底怎么平衡
3.1 极端策略为什么都不好:3.5题的中间路线
教材3.5题抛出一个很现实的矛盾:系统里既有就绪态进程,又有就绪/挂起态进程,而且挂起态里有些进程优先级很高。这时候分派器怎么办?策略一,永远优先分派就绪态进程,好处是减少交换操作,因为挂起态进程一旦被选中就得先从磁盘调回内存,费时费力。坏处是高优先级进程可能饿死。策略二,永远选最高优先级的,哪怕它在磁盘上,好处是优先级严格保证,坏处是频繁交换,系统吞吐量暴跌。
习题答案给出的中间策略是:给就绪/挂起态进程的优先级打个折扣,降一到两级。这样只有当它的原始优先级比就绪态最高优先级还高出好几个级别时,才会被选中。通俗地说,就是“你虽然重要,但请你先从冰箱里出来再谈重要程度,出来这个过程本身要扣点分”。这个策略的精髓在于,它承认交换有成本,但又不完全无视优先级。
这种题在“操作系统答案”里属于典型的策略设计题,没有唯一正确答案,考的是你能不能说出权衡。你如果只答“选优先级高的”或者“选就绪态的”,都拿不到满分。必须指出交换成本和优先级保证之间的张力,然后给出一个可操作的折中方案。
3.2 从银行家算法看资源分配:安全序列到底在安全什么
教材6.5题的银行家算法是资源管理里的经典。题目给了六个进程、四类资源,问当前状态是否安全。所谓安全,就是存在一个进程序列,使得每个进程都能拿到它需要的最大资源并顺利完成。习题答案里给出的安全序列是P4、P5、P3、P2、P1、P0,每完成一个进程,它占用的资源就释放回系统,供后面的进程使用。
这个算法的现实意义在于:操作系统在分配资源之前,先模拟一下“如果我把资源给你,后面会不会死锁”。如果模拟结果显示存在安全序列,就分配;否则就让你等着。这就像银行放贷前先算你的现金流,确保你借了钱还能还上,不会把银行拖垮。银行家算法名字就是这么来的。
但要注意,银行家算法在实际系统中很少直接用,因为它要求预先知道每个进程的最大资源需求,这个信息很难准确获得。而且每次分配都要做安全性检查,开销不小。所以它更多是教学工具,帮你理解“安全状态”和“死锁避免”的概念。习题答案里让你计算需求矩阵、工作数组变化,就是在训练这套思维。
3.3 并发程序的坑:5.3和5.4题为什么能打印出奇怪的值
教材5.3题里,两个进程各自对共享变量x做减一再加一,理论上x应该始终是10。但习题答案告诉你,由于指令交替执行,可能打印出“x is 8”甚至“x is 10”以外的值。原因在于x = x - 1这行代码在机器层面是三条指令:加载x到寄存器、寄存器减一、存回x。如果两个进程的这六条指令以某种顺序交错,就会丢失更新。
5.4题的tally变量更典型。两个进程各做50次tally++,最终结果的范围是[2, 100]。下界2是怎么来的?习题答案给了一个极端的交错场景:进程A加载tally为0,加到1但还没存回;进程B加载tally还是0,做完49次增加存回49;进程A存回1覆盖了49;进程B再加载1,最后存回2。整个过程两个进程各做了50次增加,但最终只有2。这就是并发编程里著名的“丢失更新”问题。
这些题的价值在于,它们用最简短的代码让你亲眼看到:并发不是简单的“同时执行”,而是指令级别的交错。你如果以后要写多线程程序,这些习题答案里的反例就是血泪经验。每次你觉得“加个锁没必要”的时候,想想tally等于2的场景。
4. 易混概念辨析:这些坑你大概率踩过
4.1 阻塞态和挂起态到底差在哪
易混点:很多人把阻塞态和挂起态都当成“进程在等待”,觉得差不多。为什么混:两者确实都表示进程不能继续执行,而且都涉及等待。怎么区分:阻塞态是进程在内存里等I/O或事件,它还在内存中占着位置,一旦事件完成就能回到就绪态。挂起态是进程被换到磁盘上了,它不在内存里,即使等待的事件完成了,也得先从磁盘调回内存才能继续。通俗地说,阻塞是“在候诊室等叫号”,挂起是“被请出医院大门,等电话通知再来”。
4.2 就绪态和运行态的边界不是“有没有CPU”
易混点:以为就绪态就是没CPU,运行态就是有CPU。为什么混:从硬件角度看确实如此,但操作系统视角下,这个区分不够精确。怎么区分:就绪态是“万事俱备,只欠分派器选中”,运行态是“已经被选中,正在CPU上执行”。关键差别在于,就绪态进程随时可以被分派,而运行态进程一旦时间片用完或被抢占,就回到就绪态。分派器是唯一的裁判,它说谁运行谁才运行。
4.3 抢占和非抢占调度的区别不在“是否中断”
易混点:以为抢占就是“强行打断”,非抢占就是“不打断”。为什么混:抢占确实涉及打断,但非抢占也不是完全不打断,而是只在特定时机切换。怎么区分:非抢占调度下,进程一旦运行就一直跑到阻塞或主动让出CPU,操作系统不会因为时间片到就把它换下来。抢占调度下,时间片到、更高优先级进程到达,都会触发切换。教材3.5题讨论的交换策略,在抢占和非抢占语境下答案会不同。
4.4 信号量的P操作和V操作顺序不能随便换
易混点:觉得semWait和semSignal就是一对加减操作,先写哪个无所谓。为什么混:单看代码,s--和s++确实对称。怎么区分:在实现互斥时,P操作必须在临界区之前,V操作必须在临界区之后。如果顺序写反,互斥就失效了。教材5.16题还指出,用二元信号量实现一般信号量时,如果semWait和semSignal的delay操作顺序不对,会导致delay变量超出范围。这种细节在“操作系统第八版习题答案”里是明确考到的。
4.5 安全状态和不发生死锁不是一回事
易混点:以为系统处于安全状态就一定不会死锁,不安全状态就一定会死锁。为什么混:安全状态的定义确实和死锁避免紧密相关。怎么区分:安全状态是“存在至少一个安全序列”,系统按这个序列分配资源就不会死锁。不安全状态是“找不到安全序列”,但此时系统还没死锁,只是有可能死锁。就像你现金流紧张但还没破产,只是有破产风险。银行家算法只保证不进入不安全状态,不保证所有不安全状态都会死锁。
5. 什么时候该翻这份习题答案,什么时候别翻
这份“操作系统第八版习题答案”最适合的场景,是你已经看过教材对应章节,但做题时卡住了,需要有人点一下思路。比如3.1题的状态转换事件,你如果连就绪和阻塞的区别都还没搞清,直接看答案只会记住六条结论,下次换个问法又不会了。正确的用法是:先自己画一遍状态转换图,标出你认为的事件,再对照答案看哪里想漏了。3.2题那种时刻表题,更是必须自己画表格推导,看答案只能验证结果,不能替代过程。
另一种适合的场景是考前复盘。5.3和5.4题的并发交错,如果你平时没时间亲手模拟指令序列,看答案里的反例可以快速建立“并发有坑”的意识。6.5题的银行家算法,看答案里的安全序列和工作数组变化,能帮你理清计算步骤。但要注意,习题答案里的解法不一定是最优的,有些题存在多种正确解法,比如3.5题的中间策略就可以有不同的优先级折扣方案。
那什么时候别翻?如果你连教材里进程状态的基本定义都没看过,直接刷题看答案,效率极低。还有,如果你正在做课程设计或实际项目,遇到并发问题,这份习题答案帮不了你——它给的是教学场景下的简化模型,真实系统里的线程同步要复杂得多。另外,如果你指望靠背答案通过考试,风险很大,因为操作系统题很容易变形,同一个知识点换个场景你就认不出来了。
我自己的习惯是:第一遍做题时把答案盖住,哪怕想半小时也不翻。第二遍对答案时,重点看自己推导过程和答案的差异,而不是只看最终结果。第三遍考前,只翻那些当时卡住的题,重新推一遍。从那以后我每次复习操作系统,都强制走一遍“先推导、再对答案、再复盘差异”的流程,比单纯刷题效果好得多。希望这份习题答案能帮你把操作系统里那些绕来绕去的状态和调度真正搞懂,而不是只记住几个结论。
本文还有配套的精品资源,点击获取