同学们,操作系统是 408 里「背多分」和「算多分」五五开的科目:PV 操作的大题靠模板,磁盘调度和 TLB 的计算靠公式。这份讲义把两类都备齐——代码背下来,公式套模板,35 分到手。
一、进程与 PV 操作:大题第一钉子户
1.1 信号量语义
P(wait):S−−,S<0 则阻塞;V(signal):S++,S≤0 唤醒一个等待进程。
S 的值的含义:S>0 表示可用资源数;S<0 时 |S| = 等待队列中的进程数——选择题年年考这个绝对值。
1.2 生产者-消费者(标准答案,一字不差地背)
semaphore mutex = 1; // 互斥访问缓冲区semaphore empty = n; // 空缓冲区数semaphore full = 0; // 产品数
producer() { consumer() { while (1) { while (1) { 生产一个产品; P(full); P(empty); // ① P(mutex); P(mutex); // ② 取出一个产品; 放入缓冲区; V(mutex); V(mutex); V(empty); V(full); 消费产品; } }} }【头号易错】P(mutex) 必须在 P(empty/full) 之后!先锁门再等资源,别人想取产品放资源都进不来——经典死锁写法,大题写了这两行交换直接一半分没了。对「申请资源」类信号量和「互斥」类信号量,口诀:先资源、后互斥;V 操作顺序无所谓。
1.3 读者-写者(读优先版)
semaphore mutex = 1; // 保护 countsemaphore rw = 1; // 读写互斥int count = 0; // 正在读的读者数
writer() { reader() { P(rw); P(mutex); 写文件; if (count == 0) P(rw); // 第一个读者锁门 V(rw); count++;} V(mutex); 读文件; P(mutex); count--; if (count == 0) V(rw); // 最后一个读者开门 V(mutex); }理解骨架:第一个读者负责锁门、最后一个读者负责开门。「写优先/读写公平」版本加一个 w=1 的信号量排队即可,考得少,懂原理即可应对。
1.4 哲学家进餐
死锁根源:人人先拿左叉。三种解法任答其一:① 最多允许 4 人同时拿叉(加信号量 count=4);② 奇数号先左偶数号先右(相邻必然错开);③ 仅当两把叉都可用才允许拿起(AND 信号量/一次性 P)。答「限 4 人」最简单,写大题首选。
1.5 进程调度算法
FCFS、SJF(平均等待时间最短)、HRRN 响应比 =(等待 + 执行)/ 执行、优先级、时间片轮转。
周转时间 = 完成 − 到达;带权周转 = 周转 / 执行(≥ 1)。给甘特图算表题是固定题型,注意时间片轮转的切换开销。
二、死锁与银行家算法
- 四必要条件:互斥、占有并等待、不可剥夺、循环等待(缺一不死锁;破坏任意一条即预防)
- 处理策略:预防(静态,如一次申请全部资源)→ 避免(银行家算法,动态)→ 检测(资源分配图化简)→ 解除(剥夺/撤销)
银行家算法五步(大题模板)
- 算 Need = Max − Allocation(先把这张表算对,全题的命)
- Work = Available,Finish[i] = false
- 找 Needᵢ ≤ Work 且未完成的进程 i;找不到 → 转第 5 步
- Work += Allocationᵢ;Finish[i] = true;记录进程号;回到 3
- 全部 Finish = true → 安全序列(按记录顺序写);否则不安全
【提醒】安全序列可能不唯一,题目问「是否存在」时任给一条即可;问「全部序列」才枚举。若问「分配后是否仍安全」,先试分配再跑上述流程。
三、内存管理:计算题重灾区
3.1 动态分区分配
四种算法:首次适应(空闲区按地址递增,效果通常最好)、最佳适应(产生最多小碎片)、最坏适应、邻近适应。碎片判断:动态分区产生外部碎片,分页产生内部碎片,分段产生外部碎片——三种对应关系必背。
3.2 分页地址变换与 TLB(必考计算)
页大小 2^k → 逻辑地址低 k 位是页内偏移,高位是页号。
【模板】TLB 命中率 90%,TLB 访问 10ns,内存访问 100ns,页表访问也要访存一次:
- 命中:查 TLB + 一次访存;未命中:查 TLB + 查页表 + 访问数据(若题设 TLB 与页表同时查询则未命中分支少一次 TLB 时间——看清题干假设)
- 多级页表减少的是页表占用的内存,代价是增加访存次数
- 快表(TLB)由硬件实现,属相联存储器
3.3 页面置换算法(给访问串画表)
| 算法 | 规则 | 坑 |
|---|---|---|
| OPT | 淘汰未来最久不使用 | 考试可算,实际无法实现 |
| FIFO | 淘汰最早进入 | Belady 异常:物理块增多缺页可能反增 |
| LRU | 淘汰最近最久未用 | 堆栈类算法,无 Belady 异常;实现开销大 |
| Clock | 循环扫描访问位,二机会 | 改进型 Clock 兼顾修改位,跳过脏页优先淘汰干净页 |
【画表纪律】缺页数:凡是目标页不在内存、需要调入的都算——包括第一次装入的页;置换次数:只数内存已满后被换出的次数。两个概念分开统计,大题专门考你数得对不对。另外:缺页中断属于内中断(故障 fault),选择题考过不止一次。
四、文件管理
4.1 物理结构
| 结构 | 特点 | 随机访问 |
|---|---|---|
| 连续分配 | 目录记起始块+长度,随机访问最快,有外部碎片 | 支持 |
| 隐式链接 | 每块存下一块指针,只能顺序访问,指针浪费 | 不支持 |
| 显式链接 | FAT 表全内存,查表即定位 | 支持 |
| 索引分配 | 每文件一张索引表 | 支持 |
4.2 多级索引(UNIX 风格计算题)
设块大小 4KB、地址项 4B → 每块可存 1024 个地址:
- 直接块 10 个:40KB
- 一级间接:1024 × 4KB = 4MB
- 二级间接:1024² × 4KB = 4GB
- 三级间接:1024³ × 4KB = 4TB
文件最大长度 = 各级累加。给「文件超出多少字节后用到二级间接」这种问法,就是拿 40KB + 4MB 当阈值卡。
4.3 目录与共享
FCB / 索引结点(inode)把文件名与描述信息分离;硬链接(多个目录项指向同一 inode,计数归零才删)vs 符号链接(存路径,属软链接,原文件删后成悬空)。
五、I/O 与磁盘:最后的计算题
5.1 缓冲区公式(背!)
单缓冲:每块耗时 = max(C, T) + M;双缓冲:max(C + M, T)(C 计算/处理时间,T 输入时间, M 缓冲区传送时间)。给「处理 10 块数据共多久」先套公式再乘块数,注意双缓冲下输入可与处理重叠。
5.2 SPOOLing(假脱机)
用输入井/输出井(磁盘)+ 输入/输出缓冲区 + 进程模拟,把独占设备改造成共享设备——「将一台物理设备虚拟成多台逻辑设备」,打印机并发就是标准例子。选择题考「井是什么」:井在磁盘上。
5.3 磁盘调度(给磁道序列算总移动数)
【例】当前磁头在 100 号,请求队列:55, 58, 39, 18, 90, 160, 150, 38, 184。
- FCFS:按队列走,总移动 = |100−55|+|55−58|+… 直接累加
- SSTF(最短寻道优先):每次选最近 → 90→58→55→39→38→18→160→150→184,总移动 268 道。会产生饥饿
- SCAN(电梯,沿当前方向扫到最远请求再折返):向大 → 150→160→184 折返 → 90→58→55→39→38→18,共 250 道;若题目要求走到磁盘边缘(如 199)再折返则算到端点。C-SCAN 到端点后直接跳回起点再单向扫;LOOK/C-LOOK 是「不到端点、到最远请求即折返」的简化版
【提醒】答题先写「假设当前方向向磁道号增大/减小」——不声明方向,答案对也可能扣步骤分。
冲刺建议:操作系统的复习优先级很明确:① 生产者-消费者的标准代码默写到一字不差;② 银行家算法表格题手算 5 遍;③ 置换算法和磁盘调度各画 3 张表。这三样占掉这门课大题的八成出镜率。剩余的概念题用碎片时间过,性价比一样高。最后两个月,稳住,能赢。