简介:这份山东大学操作系统期末复习笔记面向准备操作系统课程期末考核的本科生,尤其适合需要系统梳理考点、快速回顾核心概念的同学。内容围绕操作系统导论、系统结构、进程管理、存储管理、文件管理、设备管理、作业管理与文件系统管理展开,重点覆盖进程与程序的区别、进程三态转换时机、PCB组成、调度队列、进程间通信的消息传递与共享内存对比,以及Simple structure、Layered、Microkernel三种结构设计的优劣分析,并配有代码题相关要点提示。资源包为1个PDF文件,大小约2.91MB,单文件结构便于直接阅读和打印复习。目前已有974人学习下载,说明该笔记在同类复习资料中具有一定参考价值。读者可借助它建立从概念到状态转换、从系统调用到结构设计的完整知识框架,适合考前查漏补缺与重点强化。
1. 操作系统期末复习:从「背了忘」到「考场能推」的复习路径
操作系统期末复习最让人头疼的地方在于:概念多、机制绕、计算题还容易翻车。你背了进程调度算法,考试给你一个甘特图画错;你记了页面置换,题目里访问序列一长就乱。更麻烦的是,很多同学复习时把「看懂」当成「会做」,结果一上考场发现根本推不出来。
这篇笔记面向正在准备操作系统期末的本科生,尤其是那些「课听了、书翻了、题还是不会做」的情况。我会把复习拆成三条线:概念线(用一句话说清机制)、计算线(调度、置换、磁盘、银行家算法)、综合线(PV操作、死锁、文件系统)。每条线都给出可复现的推导步骤和自检方法,不堆术语,只讲考场怎么用。
复习的核心逻辑是:操作系统不是背出来的,是推出来的。你只要能复现调度过程、能画出资源分配图、能写出PV操作的伪代码,大部分题就能拿分。下面从最容易被低估的「计算题手推流程」开始。
2. 计算题手推流程:调度、置换、磁盘、银行家
计算题是操作系统期末最容易拉开差距的部分。选择题靠印象还能蒙,计算题不会就是零分。这一章把四类高频计算题的推导过程拆成可复现的步骤,每类都给一个最小例子,你照着推一遍就能上考场。
2.1 进程调度:先画时间轴,再算周转时间
调度题最常见的翻车点是「响应比」和「周转时间」混在一起算。我一般会先画一条时间轴,把到达时间、服务时间标上去,然后按算法规则逐个填。
以FCFS、SJF(非抢占)、SRTF(抢占)、RR(时间片q)为例,假设有4个进程:
| 进程 | 到达时间 | 服务时间 |
|---|---|---|
| P1 | 0 | 7 |
| P2 | 2 | 4 |
| P3 | 4 | 1 |
| P4 | 5 | 4 |
手推步骤:
- 画时间轴,从0开始。
- FCFS:按到达顺序执行,P1(0-7)、P2(7-11)、P3(11-12)、P4(12-16)。
- SJF非抢占:0时刻只有P1,必须执行完;7时刻P2、P3、P4都到了,选服务时间最短的P3(1),再P2(4),再P4(4)。
- SRTF:每次有新进程到达就比较剩余时间。0-2跑P1,2时刻P2到达,P1剩5,P2需4,切换P2;4时刻P3到达,P2剩2,P3需1,切换P3;5时刻P4到达,P3剩0(刚好跑完),此时P2剩2、P4需4,选P2;P2跑完后再P4,最后P1。
- RR q=2:就绪队列轮转,注意新到达进程先入队。
周转时间 = 完成时间 - 到达时间;带权周转时间 = 周转时间 / 服务时间。
注意:SRTF的切换点只在「新进程到达」和「进程完成」两个时刻,不要在每个时间单位都切换。
参数说明:时间片q越小,响应越快但切换开销越大;SJF对短作业友好,但长作业可能饿死。考试里如果题目没给q,RR默认按题目给的数字,不要自己假设。
2.2 页面置换:访问序列逐行打表,别跳步
页面置换题的核心是「物理块数」和「访问序列」。常见算法:FIFO、LRU、OPT、Clock。翻车最多的是LRU,因为要维护最近使用顺序。
以访问序列 7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1,物理块3个为例:
FIFO手推:
| 访问 | 块1 | 块2 | 块3 | 缺页 |
|---|---|---|---|---|
| 7 | 7 | 是 | ||
| 0 | 7 | 0 | 是 | |
| 1 | 7 | 0 | 1 | 是 |
| 2 | 2 | 0 | 1 | 是 |
| 0 | 2 | 0 | 1 | 否 |
| 3 | 2 | 3 | 1 | 是 |
| ... |
LRU手推:每次访问后把该页移到「最近使用」端,淘汰最久未用的。建议用一个小列表维护顺序,不要只画块。
OPT:看未来最远才用的页淘汰。考试里OPT用来算理论下限,实际不会考太复杂。
注意:缺页次数和缺页率是两回事,缺页率 = 缺页次数 / 总访问次数。题目问「缺页率」时别只写次数。
2.3 磁盘调度:先排序,再算移动距离
磁盘调度常考FCFS、SSTF、SCAN、C-SCAN。核心是「当前磁头位置」和「移动方向」。
假设磁头在53,请求序列:98,183,37,122,14,124,65,67。
SSTF:每次选最近的。53→65(12)→67(2)→37(30)→14(23)→98(84)→122(24)→124(2)→183(59),总移动 = 12+2+30+23+84+24+2+59 = 236。
SCAN(向大方向):53→65→67→98→122→124→183→(到头)→37→14,总移动 = (183-53)+(183-14) = 130+169 = 299。
C-SCAN:单向扫描,到头直接回起点再扫。53→65→67→98→122→124→183→(回0)→14→37,总移动 = (183-53)+183+37 = 130+183+37 = 350。
注意:SCAN和C-SCAN的方向要看题目有没有指定,没指定就按「向磁道号增大方向」默认,并在答案里写明假设。
2.4 银行家算法:画表 + 找安全序列
银行家算法题一般给Allocation、Max、Available,求Need和安全序列。
步骤:
- Need = Max - Allocation。
- Work = Available。
- 找Need ≤ Work的进程,假设它完成,Work += Allocation。
- 重复直到所有进程完成,或找不到可完成进程(不安全)。
| 进程 | Allocation | Max | Need | Work |
|---|---|---|---|---|
| P0 | 0 1 0 | 7 5 3 | 7 4 3 | 3 3 2 |
| P1 | 2 0 0 | 3 2 2 | 1 2 2 | |
| P2 | 3 0 2 | 9 0 2 | 6 0 0 | |
| P3 | 2 1 1 | 2 2 2 | 0 1 1 | |
| P4 | 0 0 2 | 4 3 3 | 4 3 1 |
安全序列:P1→P3→P4→P0→P2(或P1→P3→P4→P2→P0,看具体Work变化)。
注意:安全序列不唯一,只要写出一个合法的就行。但「不安全」的结论必须所有分支都试完才能下。
3. PV操作与死锁:从信号量语义到代码落地
PV操作是操作系统期末的「大题常客」,也是很多人丢分的地方。不是不会写wait/signal,而是搞不清信号量的初值该设多少、多个信号量怎么配合。这一章从信号量语义讲起,落到三类经典模型的代码模板。
3.1 信号量初值怎么定:看资源数量和同步关系
信号量分两类:互斥信号量初值一般为1,资源信号量初值为资源数量,同步信号量初值看「谁等谁」。
- 互斥:mutex = 1,P(mutex)和V(mutex)成对出现。
- 资源:empty = N(缓冲区空位数),full = 0(已放产品数)。
- 同步:如果A必须等B做完才能做,设一个信号量S=0,B做完后V(S),A开始前P(S)。
常见翻车:把互斥信号量和资源信号量的P顺序写反,导致死锁。正确顺序是先P资源,再P互斥。
3.2 生产者-消费者:缓冲区满和空的判断
semaphore mutex = 1; // 互斥访问缓冲区 semaphore empty = N; // 空缓冲区数量 semaphore full = 0; // 已放产品数量 // 生产者 while (1) { produce_item(); P(empty); // 先申请空位,没有就阻塞 P(mutex); // 再申请互斥锁 put_item(); V(mutex); V(full); // 通知消费者有产品了 } // 消费者 while (1) { P(full); // 先申请产品,没有就阻塞 P(mutex); get_item(); V(mutex); V(empty); // 通知生产者有空位了 consume_item(); }逻辑说明:P(empty)必须在P(mutex)之前,否则生产者拿到锁后发现没空位,阻塞时锁没释放,消费者也进不来,直接死锁。V的顺序无所谓,但一般先释放互斥再通知对方。
参数说明:N是缓冲区大小,考试里如果题目说「缓冲区容量为10」,就设empty=10、full=0。mutex初值永远是1。
3.3 读者-写者:读优先和写优先的区别
读者-写者问题有两种倾向:读优先(读者不断来,写者饿死)和写优先(写者来后阻止新读者)。
读优先版本:
semaphore rmutex = 1; // 保护readcount semaphore wmutex = 1; // 读写互斥 int readcount = 0; // 读者 P(rmutex); if (readcount == 0) P(wmutex); // 第一个读者锁住写 readcount++; V(rmutex); read_data(); P(rmutex); readcount--; if (readcount == 0) V(wmutex); // 最后一个读者释放写 V(rmutex); // 写者 P(wmutex); write_data(); V(wmutex);写优先版本需要再加一个信号量w,读者来的时候先P(w),写者来的时候也P(w),这样写者一到就能挡住后续读者。
注意:readcount是共享变量,必须用rmutex保护。考试里如果只写P(wmutex)不写rmutex,会被扣分。
3.4 死锁四个必要条件与银行家算法的关系
死锁四个条件:互斥、占有并等待、不可抢占、循环等待。银行家算法是「避免死锁」,不是「预防死锁」。预防是破坏四个条件之一,避免是动态检查安全性。
考试里如果问「银行家算法破坏了哪个条件」,答案是:它没有破坏任何一个,而是通过安全性检查避免进入不安全状态。这个点很多人答错。
4. 内存管理与文件系统:分页、分段、inode计算
内存管理和文件系统是概念+计算混合区。分页分段考地址转换,文件系统考inode和磁盘块计算。这一章把公式和手推步骤对齐。
4.1 分页地址转换:页号、页内偏移、物理地址
逻辑地址 = 页号 × 页面大小 + 页内偏移。物理地址 = 物理块号 × 页面大小 + 页内偏移。
例:页面大小4KB,逻辑地址0x2A3F,页号 = 0x2A3F / 0x1000 = 2,偏移 = 0x2A3F % 0x1000 = 0xA3F。查页表得物理块号5,物理地址 = 5 × 0x1000 + 0xA3F = 0x5A3F。
注意:页面大小是2的幂时,页号就是逻辑地址右移log2(页面大小)位,偏移就是低位。手算时用十六进制更快。
4.2 分段与段页式:段表、页表两级查
分段:逻辑地址 = 段号 + 段内偏移。段表项含段长和基址。先查段表,检查偏移 < 段长,物理地址 = 基址 + 偏移。
段页式:先查段表得页表基址,再查页表得物理块号,最后拼物理地址。考试里段页式一般只考「几次访存」,答案是3次(段表、页表、数据),有TLB则可能减少。
4.3 inode与磁盘块:直接、一级、二级、三级间接
inode里存文件元数据和块指针。假设inode有12个直接指针、1个一级间接、1个二级间接、1个三级间接,块大小4KB,每个指针4B。
- 直接:12 × 4KB = 48KB
- 一级间接:4KB / 4B = 1024个指针,1024 × 4KB = 4MB
- 二级间接:1024 × 1024 × 4KB = 4GB
- 三级间接:1024^3 × 4KB = 4TB
最大文件 = 48KB + 4MB + 4GB + 4TB。
注意:题目如果问「访问某个偏移需要几次磁盘I/O」,要算上读inode、读间接块、读数据块。直接指针1次数据I/O,一级间接2次,二级间接3次。
4.4 页面置换与工作集:缺页率计算
工作集模型用来防止抖动。工作集W(t, Δ) = 最近Δ次访问中出现的页面集合。如果工作集大小 > 物理块数,就会频繁缺页。
考试里一般给访问序列和Δ,让你算工作集大小。手推时维护一个窗口,每次滑动去掉过期的,加入新的。
5. 避坑与排查:期末考场上最容易翻车的5个点
这一章是我自己复习和帮别人看题时总结的翻车记录,每条按「现象→原因→解决」写。考前过一遍,能少丢10分。
5.1 调度题算错周转时间:把「完成时间」和「开始时间」搞混
现象:周转时间算出来比服务时间还小。 原因:周转时间 = 完成时间 - 到达时间,不是开始时间 - 到达时间。 解决:画时间轴时标清楚每个进程的「开始」和「完成」,算周转只用完成时间。
5.2 LRU置换表跳步:只画块不维护顺序
现象:LRU缺页次数和FIFO一样,或者淘汰的页不对。 原因:LRU需要知道「最近最久未使用」,只画物理块看不出顺序。 解决:在草稿纸上维护一个访问顺序列表,每次访问把该页移到最前,淘汰时选最后。
5.3 PV操作P顺序写反:先P互斥再P资源
现象:生产者-消费者代码看起来对,但分析时发现会死锁。 原因:先P(mutex)再P(empty),如果empty=0,生产者阻塞时持有mutex,消费者无法进入。 解决:永远先P资源信号量,再P互斥信号量。V的顺序相反。
5.4 银行家算法漏试分支:找到一个安全序列就停
现象:题目问「是否安全」,你写安全,但标准答案是不安全。 原因:安全序列不唯一,但如果不安全,必须所有可能都试完才能下结论。 解决:按Need ≤ Work逐个试,如果某一步有多个可选,标记后继续;如果所有分支都走不通,才是不安全。
5.5 地址转换忘记检查越界:段式存储必须查段长
现象:分段地址转换直接加基址,没检查偏移是否超过段长。 原因:段式存储的段表项有段长,越界会产生越界中断。 解决:先比较偏移 < 段长,再算物理地址。题目如果给「合法/非法」,非法就是越界。
6. 考前72小时:用「三遍推演法」把计算题变成肌肉记忆
最后这一章讲一个我自己考前用的方法:三遍推演法。不是刷题,是把同一道题用三种方式推三遍,直到不用想就能写。
第一遍:看着答案推。把调度题、置换题、PV题各选一道,对着答案一步步写,写的时候问自己「这一步为什么是这个进程/这个页」。这一遍的目的是建立正确流程。
第二遍:合上答案推。拿一张白纸,只抄题目,从头推。卡住的地方标记,推完再对答案。这一遍会暴露你「以为会」其实不会的点。
第三遍:改参数推。把题目里的时间片从2改成3,把物理块从3改成4,把缓冲区从10改成5,再推一遍。这一遍是防止考场题目变型后你不会。
具体操作表:
| 题型 | 第一遍重点 | 第二遍重点 | 第三遍重点 |
|---|---|---|---|
| 调度 | 画时间轴 | 算周转/带权 | 改q或改到达时间 |
| 置换 | 打表 | 算缺页率 | 改块数或序列 |
| PV | 写伪代码 | 分析死锁 | 改缓冲区大小 |
| 银行家 | 找安全序列 | 判断安全性 | 改Available |
注意:第三遍不要贪多,每类改1-2个参数就行。目的是让你在考场看到「没见过」的题时不慌。
我自己的习惯是考前两天只做三件事:推一遍调度、推一遍置换、默写一遍PV。其他概念题用零碎时间过。这样上考场,计算题基本不会翻车。
希望帮到你。
本文还有配套的精品资源,点击获取