
后台总有人私信问“操作系统第二章课后题答案有没有”一问基本都用的是同一本教材——汤小丹版的《计算机操作系统》现在很多学校用的是配套慕课的版本也就是大家常说的“慕课版”。我通常的回复是答案给你整理没问题但你先别急着背。第二章“进程管理”是整门课真正的分水岭选择题、简答题、PV大题、调度计算题全从这里面出。这篇就按课后题里最高频的考点把概念题、状态转换、调度算法、同步与互斥题目完整拆一遍顺带把大家复习时最容易踩的坑也列出来。课程初学者可以当学习笔记看考研复习的同学可以拿来做考点速查期末突击的也能直接对着核心结论用。1. 第二章的知识地图课后题到底在考什么1.1 进程管理为什么会成为“劝退章”很多同学学操作系统第一章概论还能跟上一到第二章就开始懵。原因是第一章讲的是“操作系统是什么、有什么功能”相对具象第二章上来就是“进程”你看不见摸不着它不像文件、磁盘那样有实体而是一个动态的概念。同一个程序跑两次会产生两个进程程序暂停再继续进程状态还要发生变化。这种抽象程度对第一次接触操作系统的同学来说确实不友好。但正因为抽象它才是这门课的重中之重。进程管理决定了操作系统如何分配CPU、如何调度任务、如何保证多个程序同时运行而不互相干扰。可以说理解了进程才算真正开始理解操作系统。所以这一章不是“背一背就能过”而是要建立起动态、并发、资源共享的思维模式。课后题的目的也正在于此它不是让你复述概念而是逼着你把进程的状态、PCB、同步、调度这些知识点串起来。1.2 教材里的知识点主线汤小丹版教材第二章的内容跨度不小我习惯把这章的知识点画成一条主线进程的定义与特征 → 进程的描述PCB → 进程的控制创建、阻塞、唤醒、撤销 → 进程同步与互斥 → 进程通信 → 线程的基本概念最后以调度算法收尾。课后题基本就是围绕这条主线每一段配几道题。也就是说如果你能把这几个环节在自己脑子里串成一条“进程从创建到结束的一生”整章就没那么散了。进程被创建时系统会给它分配一个PCB进程运行中会因为等待I/O而阻塞也可能因为时间片用完而回到就绪队列多个进程同时访问打印机这类临界资源时要靠信号量和PV操作来协调CPU到底先执行哪个进程则由调度算法决定。这个流程一旦清晰绝大多数题你都能判断出它考的是哪个环节。1.3 课后题的三大考察方向结合历年考试和课后题分布第二章的出题方向基本固定在三个维度。第一是概念辨析比如进程和程序的区别、并发和并行的区别、进程与线程的区别。这类题出现在选择、判断、简答里表面是送分题但表述稍微改一下就能绕进去很多人。第二是状态转换比如运行态、就绪态、阻塞态之间如何切换某事件发生后进程进入什么状态。第三是算法与同步设计包括调度算法的周转时间计算、写信号量实现生产者-消费者问题等。这类题一旦考就是大题占分高也是最需要动手练的部分。2. 高频概念题精讲程序、进程、线程与PCB2.1 程序与进程一组必考概念课后题里几乎必有一道“简述进程与程序的区别与联系”。很多同学背了答案但考场上换个问法又不会了。比如题目问“进程为什么具有动态性”其实就是考你对程序与进程区别的理解。标准答题要点可以归纳为五个方面程序是静态的是存储在介质上的指令序列进程是动态的是程序在数据集合上的一次执行过程。程序可以长期保存进程的生命周期是临时的创建后存在执行完就撤销。进程是系统进行资源分配和调度的独立单位程序本身不参与资源分配。程序和进程不是一一对应。同一个程序运行两次对应两个不同的进程一个进程在运行过程中也可以顺序执行多个程序。进程具有结构性它由程序、数据和进程控制块PCB三部分组成而程序不具备这种结构。答题时建议先写“本质区别静态与动态”再展开说明。阅卷时采分点往往就落在“动态”“独立调度”“PCB”这几个关键词上。如果题目要求举例子可以用“菜谱是程序炒菜的过程是进程”来类比一道菜谱可以被多个厨师同时照着炒对应同一个程序可以被多个进程执行。2.2 PCB让进程“活起来”的档案袋“进程控制块PCB的作用是什么它包含哪些内容”是第二章课后题的另一个高频考点。有的同学不理解为什么进程非要配一个PCB我的理解方式是这样的操作系统要管理成千上万个进程就必须知道每个进程“现在跑到哪了”“占用了哪些资源”“当前是什么状态”。为了实现这个目标系统为每个进程建立一张数据结构表记录它的全部现场信息这就是PCB。PCB里通常包含四大类信息进程标识信息进程号PID、父进程号PPID等用于唯一识别进程。处理机状态信息程序计数器、通用寄存器、程序状态字等用于进程切换时保存和恢复现场。进程调度信息进程状态、优先级、等待原因等用于调度器决定下一步执行谁。资源信息打开的文件列表、占用内存信息等用于系统掌握资源占用情况。课后题常考的一个变形是“进程创建时操作系统需要做哪些事情”这类题就可以从PCB切入先申请一个空白PCB并分配唯一进程标识再为进程分配所需的资源内存空间、文件等接着初始化PCB填入进程名、状态为就绪态、设置优先级最后把进程插入就绪队列等待调度。你把这个流程当成“给新员工办入职手续”就很好记建档案、分工位、填入职表、排队等开工。2.3 进程状态转换选择题高发区教材里的三态模型是就绪态、运行态、阻塞态五态模型则在此基础上增加了创建态和终止态。课后选择题几乎绕不开状态转换的触发条件最常见的几种要烂熟于心。运行态 → 就绪态通常是时间片用完或者被更高优先级进程抢占运行态 → 阻塞态一般是进程等待某事件发生比如请求I/O、等待信号量阻塞态 → 就绪态则是等待的事件已完成比如I/O结束、信号量被释放就绪态 → 运行态是被调度程序选中获得了CPU使用权。需要额外注意的是就绪态不能直接转阻塞态阻塞态也不能直接转运行态。“就绪 → 阻塞”这种说法在选择题里出现就是来迷惑你的因为就绪态进程已经在等CPU了不需要再去等资源而阻塞态进程必须先回到就绪态排队再由调度器选择执行。理解了状态转换的“单向路径”这类题基本不会错。3. 调度算法计算题用手算把流程吃透3.1 为什么要先学调度算法调度算法是第二章课后题里最容易拿分也最需要细心的一类。考察方式很直接给你几个进程的到达时间和服务时间让你按某种算法计算完成时间、周转时间、带权周转时间再比较哪种算法更优。这类题难在不是算不出来而是很容易把“开始时间”和“完成时间”搞混。先明确三个基本定义周转时间 完成时间 - 到达时间带权周转时间 周转时间 / 服务时间平均周转时间和平均带权周转时间则是对所有进程分别求平均。带权周转时间的含义可以理解为“每个进程等待的相对代价”值越接近1说明进程从进入到完成的过程越顺利。书中反复对比的先来先服务FCFS、短作业优先SJF和时间片轮转RR都是围绕这些指标展开的。下面用一个具体例子把三种算法完整演算一遍。3.2 FCFS和SJF的完整演算假设系统中有三个进程到达时间和服务时间如下表所示进程到达时间服务时间A05B13C21先看先来先服务FCFS。核心规则是“谁先到谁先执行”进程A在0时刻到达立即执行0~5B在1时刻到达但只能等A结束所以B在5~8执行C在2时刻到达排在B后8~9执行。计算结果进程到达服务开始完成周转带权周转A050551B135872.33C218977平均周转时间 (5 7 7) / 3 ≈ 6.33平均带权周转时间 (1 2.33 7) / 3 ≈ 3.44。再看非抢占式短作业优先SJF。规则是“当前时刻从已到达进程中选服务时间最短的执行”。0时刻只有A到达所以先执行A0~55时刻B和C都已到达C的服务时间最短所以先执行C5~6最后执行B6~9。计算结果进程到达服务开始完成周转带权周转A050551C215644B136982.67平均周转时间 (5 8 4) / 3 ≈ 5.67平均带权周转时间 (1 4 2.67) / 3 ≈ 2.56。可以看出这个例子中SJF的平均周转时间和平均带权周转时间都优于FCFS因为C这个短作业在FCFS里被排到最后等了很久而SJF让它提前执行整体等待时间明显下降。做题时有个经验SJF的重点是判断“当前时刻哪些进程已经到达”没到达的进程即使服务时间再短也不能提前选。很多同学算错就是因为在0时刻把B和C也拉进来比较了这显然不符合规则。3.3 时间片轮转时间片大小不是随便定的时间片轮转RR是分时系统的典型算法每个进程最多连续执行一个时间片时间片用完后回到就绪队列尾部重新排队。仍用上面的例子假设时间片q 2演算过程如下0时刻就绪队列[A]A在0~2执行剩余服务时间3。2时刻A时间片用完B在1时刻已到达B排到队首执行B 2~4剩余1。C在2时刻到达排在队尾。4时刻B时间片用完队列[A, C]A执行4~6剩余1。6时刻A时间片用完队列[C, B]C执行6~7C完成周转 7 - 2 5。7时刻队列[B, A]B执行7~8B完成周转 8 - 1 7。8时刻队列[A]A执行8~9A完成周转 9 - 0 9。平均周转时间 (9 7 5) / 3 7比FCFS略差一些。这也说明RR的优势从来不是降低平均周转时间而是让所有进程都能“轮流被服务”提升交互式场景中的响应速度。从这个例子还能引出一个课后判断题常考的点时间片太大RR退化成FCFS时间片太小频繁切换导致上下文切换开销过大。时间片的设置要在“响应时间”和“系统开销”之间权衡。4. 进程同步与PV操作课后大题的标准破题模板4.1 从“临界区”到信号量PV操作是第二章大题的重灾区。课后题里“用信号量实现进程互斥/同步”这类题看上去代码很长但破题思路其实是固定的。首先要搞清三个概念临界资源是一次只允许一个进程使用的资源比如打印机临界区是进程中访问临界资源的代码段不是资源本身信号量则是用于同步和互斥的整形变量配合P操作和V操作使用。P操作可以理解为“申请资源”如果资源数量大于0则减1继续执行如果资源数量等于0则进程阻塞等待。V操作是“释放资源”资源数量加1如果此时有进程在等待则唤醒其中一个。正因为P和V能阻塞和唤醒进程它们才是解决同步问题的底层工具。初学阶段最容易犯的错是死记代码不理解为什么要用多个信号量。我的建议是拿到题目先想清楚两件事第一哪些进程之间是“互斥关系”这种关系需要一把互斥锁第二哪些进程之间是“前后依赖”的同步关系每种依赖需要对应一个资源信号量。想清楚这两点PV代码基本就能写出来了。4.2 生产者-消费者问题的完整推导生产者-消费者问题是同步章节的必考题。题目通常描述为一个大小为n的缓冲区生产者进程往缓冲区放产品消费者进程从缓冲区取产品要求生产者不能往满缓冲区放消费者不能从空缓冲区取且对缓冲区的访问要互斥进行。需要设置三个信号量mutex初值1用于互斥访问缓冲区empty初值n表示缓冲区空位数full初值0表示缓冲区已有产品数。生产者的代码结构如下while (1) { 生产一个产品; P(empty); // 申请一个空位 P(mutex); // 进入临界区 把产品放入缓冲区; V(mutex); // 退出临界区 V(full); // 产品数加1 }消费者的代码结构如下while (1) { P(full); // 申请一个产品 P(mutex); // 进入临界区 从缓冲区取出产品; V(mutex); // 退出临界区 V(empty); // 空位数加1 消费产品; }这里最关键的是顺序问题P(empty)和P(mutex)不能交换。如果生产者先P(mutex)再P(empty)一旦缓冲区已满生产者会持有mutex等待空位而消费者又因为拿不到mutex无法取产品双方互相等待直接死锁。V操作的顺序则可以交换但为了逻辑清晰还是建议先V(mutex)再V(full)。考试还喜欢出“多生产者多消费者”的变体。比如有两个生产者、两个消费者共同使用一个缓冲区池这时候互斥信号量mutex仍然只需要一个因为访问缓冲区池是整体的互斥操作但每个生产者和每个消费者都要执行同样的P和V信号量初值不变。也就是说信号量管理的是“资源数量”和“临界区互斥”与进程个数没有直接关系。4.3 读者-写者问题会套模板就不慌读者-写者问题比生产者-消费者更绕但课后题考到它时多半要求实现“读优先”。所谓读优先就是只要有一个读者在读文件后续来的读者都可以继续进入写者必须等待所有读者读完才能写并且在写者写的过程中读者和其他写者都不能进入。读优先的经典实现需要两个信号量rw用于控制读者和写者访问共享数据初值为1mutex用于保护读者计数器count初值为1。计数器count的初值为0。写者进程的代码很简单P(rw); 执行写操作; V(rw);读者进程的代码稍复杂P(mutex); count; if (count 1) { P(rw); // 第一个读者负责判断是否有写者在写 } V(mutex); 执行读操作; P(mutex); count--; if (count 0) { V(rw); // 最后一个读者负责释放文件 } V(mutex);关键在于“第一个读者要P(rw)最后一个读者要V(rw)”这是读者-写者问题最容易考的点。如果把条件判断写反比如每个读者都P(rw)会造成多个读者互相阻塞。答这类题时建议先用中文写出思路“写者互斥读者共享读者通过计数器告知自己是第几个”再转换成代码这样即使代码某处写错阅卷老师也能看到你的理解过程。5. 易错点排查与高频考点速查5.1 年年有人踩的5个坑结合批改作业和考试情况第二章里有些错误出现频率高到离谱我专门整理成了表格建议复习时对着自查一遍。易错表述正确理解并发等于并行并发是同一时间间隔内交替执行并行是同一时刻同时执行。并行需要多核CPU支持并发是单核也能实现的“宏观同时、微观交替”。临界区是资源本身临界区是访问临界资源的代码段不是资源。加锁保护的是“进入临界区”这个操作不是锁住硬件设备。进程切换等于模式切换模式切换是用户态与内核态之间的转换可以不切换进程进程切换必然伴随模式切换但两者不能画等号。P操作是“解锁”P操作是申请资源、资源数减1V操作才是释放资源、资源数加1。P和V都必须成对出现且是原子操作。阻塞态可以直接转运行态阻塞态的进程必须先进入就绪态再被调度程序选中后才能运行不存在“阻塞直接运行”的路径。最后一条经常出现在选择题的干扰项里比如“当等待的事件完成后进程从阻塞态直接转入运行态”就是一个典型错误表述正确说法是“从阻塞态转入就绪态”。5.2 死锁与饥饿别只背定义第二章有的教材会把死锁放在后面但很多课后题会在同步章节提前考察死锁概念。死锁的四个必要条件是互斥、请求保持、不可剥夺、循环等待。别小看这四句话几乎每年都有人把“循环等待”当作充分条件这就错了——四个条件缺一不可循环等待只是必要条件之一而且只是必要条件不是充分条件。饥饿则经常和死锁放在一起比较死锁是所有进程都在等待一个永远无法满足的条件谁也动不了饥饿则是某个进程长期得不到资源但其他进程还能正常运行。读者-写者问题的读优先策略如果读者源源不断写者就可能一直等不到写的机会这种现象就是饥饿。辨析题问到这里要能说清“死锁是全体停滞饥饿是部分进程被饿死”。另外“破坏死锁的四个必要条件之一就能预防死锁”这句话也常考。比如把互斥条件去掉不现实因为有些资源必须互斥访问但可以通过“一次性申请所有资源”来破坏请求保持条件通过“允许抢占”破坏不可剥夺条件通过“资源有序分配”破坏循环等待条件。这些对策在课后问答题里需要能展开写。5.3 简答题答案要点对照表课后简答题很多我把最容易抽到的几类整理成“问题采分点”的形式。背的时候不需要逐字逐句把采分点关键词记牢即可。问题答案要点关键词进程与程序的区别动态与静态、暂时与永久、进程可并发、进程有PCB、非一一对应PCB的作用记录现场信息、作为调度依据、实现进程切换、系统管理进程的依据进程的基本状态及转换就绪/运行/阻塞四类转换条件调度、时间片到、等待事件、事件完成为什么要引入线程减少程序并发执行时的时空开销同一进程内线程共享地址空间切换代价小信号量实现互斥的基本思路互斥信号量初值1进入临界区前P退出临界区后V死锁的四个必要条件互斥、请求保持、不可剥夺、循环等待复习简答题时一定要用“先定义、再分点”的格式练习。阅卷老师看一道简答的时间很短采分点能不能一眼扫到决定了你的分数。建议每道题先写一句结论性的话再列要点不要大段大段堆文字。6. 复习建议把答案变成考场上的分数6.1 慕课视频课后题的“两遍法”很多同学看慕课视频有个毛病边看边记看完觉得自己全会了合上电脑做题却卡壳。操作系统这门课光靠“看”是没有用的必须靠“练”。我自己比较推荐两遍法第一遍看视频时把教材翻到对应章节只做书上的例题视频里讲到哪道题就暂停自己先尝试写出答案再对照讲解第二遍一整章看完后隔一天再回头做课后题。为什么隔一天因为当天看完视频记忆还停留在“刚理解”的状态做题容易产生错觉仿佛是自己做出来的。隔一天再做题才能真正检验哪些知识点已经内化、哪些还需要翻书。如果第二遍还有不会的题先把那道题对应的教材页码找出来重看那一段再用自己的话把解题思路写一遍而不是直接看答案。6.2 错题本怎么写才有用错题本不是把题抄一遍、把正确答案写一遍就完了那样复习时根本不会翻。建议每条错题记录三部分题目考查的知识点、我当时写的错误答案、错因分析。错因分析尤其要具体比如“我把SJF理解成了抢占式”“我以为P(empty)和P(mutex)可以随便换顺序”“时间片轮转计算时把到达时间当成了0”等。错因写得越具体你越能发现自己思维里的固定漏洞。举个例子如果错因经常是“进程状态转换判断反了”那就说明你对状态转换的触发条件还不够敏感需要把那张转换图多看几遍如果错因是“PV操作的代码背混了”说明你还没理解P和V的本质含义需要回到信号量初值推导一遍。整理错题的过程其实就是在给自己的知识体系打补丁。6.3 考前一天的习惯性动作考前最后一天不建议再刷一堆新题更不建议通宵背答案。更高效的做法是把第二章的思维导图或目录拿出来像讲课一样给自己讲一遍——什么是PCB进程状态如何转换FCFS和SJF的优缺点生产者-消费者问题的信号量怎么设置。哪里讲不顺哪里就是你的薄弱点。另外最好亲手动笔做两道基础题不用多一道调度计算、一道PV代码题目的是把手感维持住。考试时如果遇到不会的PV题不要空着把信号量定义写上再用文字描述“生产者需要空位、需要互斥消费者需要产品、需要互斥”写思路也能拿到相当比例的过程分。这不算技巧就是阅卷的实际情况。我在实际复习时最深刻的体会是第二章的课后题做一遍根本不够至少要两到三遍。第一遍熟悉题型第二遍整理错题第三遍是在考研复习时当作重点章节重新过。尤其是PV操作刚开始可能觉得像天书但只要亲手把生产者-消费者和读者-写者的代码推导两遍就会发现它的套路极其固定。后面学进程通信、文件系统、死锁处理时还会大量用到这章的知识。所以在第二章多花的时间后面都会加倍还回来。