ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

操作系统期末高分攻略:进程、调度、内存与文件系统核心考点精讲

操作系统期末高分攻略:进程、调度、内存与文件系统核心考点精讲

简介:这份资源是面向山东大学操作系统课程期末复习的笔记资料,适合正在备考操作系统考试、需要系统梳理知识框架的本科生使用。内容围绕操作系统基本概念与功能展开,覆盖进程管理、存储管理、文件管理、设备管理、作业管理及文件系统管理等核心章节,并重点整理了进程状态转换、PCB组成、进程调度队列、父子进程与僵尸/孤儿进程、进程间通信的消息传递与共享内存对比等高频考点,同时涉及操作系统结构设计中的Simple structure、Layered与Microkernel三种方案及系统调用接口机制。资源包为1个PDF文件,大小约2.91MB,便于打印或平板阅读。目前已有974人学习下载,说明该笔记在同类复习资料中具有一定参考价值,适合用于考前快速回顾与查漏补缺。

1. 从一道“送分题”说起:操作系统期末到底考什么

“描述操作系统的概念,并解释其主要作用。”这道题几乎年年出现在卷面上,但每年都有大批人写不满三行。不是不会,是不知道阅卷人要什么。操作系统期末的套路非常固定:概念题考“关键词踩点”,计算题考“步骤完整”,代码题考“信号量/PV操作写对顺序”。整张卷子大约 60% 是记忆性内容,30% 是计算与推导,剩下 10% 是综合设计。换句话说,只要你把高频考点背成条件反射,计算题练到不假思索,这门课拿高分并不玄学。这份笔记覆盖了从导论到文件系统实现的全部章节,适合正在突击期末、想用最短时间抓住分值分布的人。下面按考点模块拆开讲,每一章都配真题思路和易错提醒。

2. 进程与线程:状态转换、PCB 与通信方式是必考三件套

2.1 进程状态转换图:四个箭头对应四种时机

进程状态转换几乎是每张卷子的第一道大题。你需要画出三态模型(就绪、运行、等待/阻塞),并标注四个转换方向:

  • 运行 → 等待:进程请求 I/O 或等待某事件发生
  • 等待 → 就绪:等待的事件已经发生
  • 运行 → 就绪:时间片用完,或有更高优先级进程抢占
  • 就绪 → 运行:被调度程序选中,分配到 CPU

阅卷时最常扣分的地方是“等待 → 运行”这个箭头。它不存在,必须经过就绪态。另一个高频追问是“进程与程序的区别”,标准答案四条:进程由程序和数据组成;程序是静态的,进程是动态的;进程有生命周期,程序相对长久;一个程序可以对应多个进程。

2.2 PCB 与进程控制:父子进程、僵尸与孤儿

PCB 是进程存在的唯一标志,包含进程标识符、状态、程序计数器、寄存器、内存指针、I/O 状态等信息。进程三要素是程序、数据、PCB。

真题常考父子进程行为。看下面这段典型代码:

#include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); // 创建子进程 if (pid == 0) { // 子进程:pid 返回 0 printf("child process\n"); } else if (pid > 0) { // 父进程:pid 返回子进程的 PID wait(NULL); // 父进程等待子进程结束 printf("parent process\n"); } return 0; }

fork()调用一次返回两次:子进程中返回 0,父进程中返回子进程 PID。写时复制意味着父子进程初始共享页面,任一方写入时才复制副本,各自变量互不影响。如果子进程终止而父进程未调用wait(),子进程变成僵尸进程;如果父进程先终止,子进程变成孤儿进程,由 init 进程收养。

2.3 进程间通信:共享内存与消息传递的取舍

共享内存和消息传递是两种基本方式。共享内存由应用程序员自己编写访问代码,操作系统只提供共享区域,优点是速度快、不需要系统调用;缺点是同步复杂,容易出竞态。消息传递由操作系统提供机制,适合交换少量数据,实现简单,但每次通信都要陷入内核。

真题问法:“描述进程间通信的两种方式,说明优缺点和适用场合。”答题模板:先定义,再对比,最后给场景。共享内存适合大数据量、高频通信;消息传递适合分布式系统或数据量小的场景。

2.4 线程:用户级与内核级的区别

线程是 CPU 使用的基本单元,引入线程是为了提高响应度、资源共享、经济性和多处理器利用。用户级线程由线程库管理,内核不感知,阻塞一个线程会导致整个进程阻塞;内核级线程由操作系统直接管理,阻塞互不影响,但切换代价接近进程。多线程模型有多对一、一对一、多对多三种。线程取消分异步撤销和延迟撤销,线程池预先创建线程等待工作。

3. CPU 调度与死锁:计算题的分值都藏在这里

3.1 调度算法:FCFS、SJF、RR 与多级反馈队列

CPU 调度是计算题重灾区。你需要掌握每种算法的周转时间、等待时间计算。

算法抢占性特点缺点
FCFS非抢占简单,先到先服务护航效果,短进程等待久
SJF非抢占平均等待时间最小长进程可能饥饿
SRTF抢占最短剩余时间优先上下文切换频繁
RR抢占时间片轮转,分时系统时间片过小开销大
优先级两者均可高优先级先执行低优先级饥饿,需老化
多级反馈队列抢占进程可在队列间移动参数最多,最复杂

真题常给一组进程到达时间和执行时间,让你算平均周转时间和平均等待时间。步骤:画甘特图 → 算每个进程完成时间 → 周转时间 = 完成时间 - 到达时间 → 等待时间 = 周转时间 - 执行时间。

3.2 死锁四个必要条件与银行家算法

死锁的四个必要条件:互斥、占有并等待、非抢占、循环等待。这四个必须同时成立才可能死锁。

银行家算法是必考计算题。核心是安全性算法:检查是否存在安全序列。给一个例子:

# 银行家算法安全性检查伪代码 def is_safe(available, max_need, allocation): work = available[:] # 当前可用资源 finish = [False] * len(max_need) safe_seq = [] while len(safe_seq) < len(max_need): found = False for i in range(len(max_need)): if not finish[i]: need = [max_need[i][j] - allocation[i][j] for j in range(len(work))] if all(need[j] <= work[j] for j in range(len(work))): work = [work[j] + allocation[i][j] for j in range(len(work))] finish[i] = True safe_seq.append(i) found = True if not found: return False, [] return True, safe_seq

available是当前可用资源向量,max_need是每个进程最大需求矩阵,allocation是已分配矩阵。need矩阵由max - allocation得到。如果找不到任何一个进程能满足,说明系统不安全。考试时手算要列表格,逐步更新 Work、Need、Allocation。

3.3 死锁检测与恢复

单实例资源用等待图,有环即有死锁。多实例资源用类似银行家算法的检测算法。恢复手段包括选择牺牲品进程、回滚、终止进程。饥饿与死锁的区别常考:死锁一定涉及循环等待且多个进程,饥饿可能只有一个进程且等待的资源会被释放但不会分配给自己。

4. 内存管理与虚拟内存:分页、分段、页面置换一网打尽

4.1 连续分配与非连续分配

连续分配分固定分区和可变分区。可变分区的分配算法有首次适应、最佳适应、最差适应。外碎片用紧缩解决,内碎片是分区内浪费的空间。

非连续分配重点是分页和分段。分页将逻辑空间等分为页,物理空间等分为帧,页表记录映射。TLB 是快表,并行查找提高效率。二级页表需要访问三次内存:一次页表、一次二级页表、一次主存。

分段按程序逻辑划分,段号加段内偏移得到物理地址。段页式是两者结合:先分段,段内分页。

4.2 页面置换算法:FIFO、LRU、时钟

虚拟内存的核心是按需调页。缺页率 = 缺页次数 / 访问页面总数。

算法置换目标特点
FIFO最先调入的页可能出现 Belady 异常
OPT未来最远才访问的页理论最优,无法实现
LRU最近最少使用的页性能好,实现开销大
时钟访问位为 0 的页二次机会,指针循环
增强时钟未使用且未修改的页使用位优先于修改位

真题常给一个访问串,让你算缺页次数。务必按步骤画表:访问页 → 内存块状态 → 是否缺页 → 置换哪一页。

4.3 系统颠簸与帧分配

颠簸是频繁调页导致换页时间大于运行时间。解决方法:局部置换、调整帧分配、页错误率策略。全局置换从所有帧中选,吞吐量更好但可能引发颠簸;局部置换只从自己帧中选,可能浪费空闲帧。

5. 文件系统与 I/O:FCB、分配方式与目录共享

5.1 文件分配:连续、链接、索引

连续分配访问性能最好,但有外部碎片,文件扩展困难。链接分配无外部碎片,但不能直接访问,指针损坏影响大。FAT 把指针集中成表,提高随机访问性能。索引分配支持直接访问,但索引块占空间。

5.2 打开文件的过程

系统调用open()将文件名传给文件系统,搜索目录找到 FCB,复制到系统打开文件表,在进程打开文件表中增加条目并指向系统表。返回指向进程打开文件表的指针。系统打开文件表包含 FCB 副本和打开计数,进程表包含指针和访问模式。

5.3 文件共享与虚拟文件系统

无环图目录结构允许同一文件出现在多个目录中。符号链接不处理悬挂链接,硬链接增加引用计数。虚拟文件系统在接口和具体实现之间加一层,统一不同文件系统。

6. 易错点与失分点:这些坑年年有人踩

6.1 进程状态转换写错方向

错在哪:把“等待 → 运行”画成直接转换。为什么错:等待态必须经过就绪态才能被调度。怎么答对:牢记只有就绪 → 运行,等待 → 就绪,运行 → 就绪,运行 → 等待四个方向。

6.2 信号量 PV 操作顺序颠倒

错在哪:生产者代码中先 P(mutex) 再 P(empty)。为什么错:如果缓冲区满,先锁互斥再等空位会导致死锁。怎么答对:生产者先 P(empty) 再 P(mutex),消费者先 P(full) 再 P(mutex),V 操作顺序相反。

6.3 银行家算法忘记检查 Need

错在哪:只比较 Request 和 Available,忽略 Need。为什么错:进程请求可能超过其最大需求。怎么答对:三步检查——Request ≤ Need,Request ≤ Available,试探分配后系统安全。

6.4 页面置换算错缺页次数

错在哪:初始内存为空时第一次访问不算缺页。为什么错:首次调入也是缺页。怎么答对:只要页面不在内存中就是缺页,包括第一次装入。

6.5 死锁与饥饿混淆

错在哪:认为饥饿一定涉及多个进程。为什么错:饥饿可能只有一个进程。怎么答对:死锁一定循环等待且多个进程,饥饿可能单个进程且资源会被释放。

7. 最后一周怎么背:从真题反推答题模板

到了考前一周,不要再从头翻书。拿三套往年题,按题型分类:概念题、计算题、代码题。概念题只背关键词,比如“操作系统功能”就背进程管理、存储管理、文件管理、设备管理、作业管理五个词,每个词展开一句话。计算题把银行家算法、页面置换、调度算法各练五遍,练到看到题目就能画表。代码题重点背生产者-消费者、读者-写者、哲学家进餐三个模型的 PV 操作顺序。

答题时注意:概念题分点写,计算题写步骤,代码题写注释。卷面留白要合理,不要挤成一团。如果遇到没见过的题,先写相关定义,再写自己的分析,阅卷老师会按点给分。

我当年期末前三天才把银行家算法彻底搞懂,之前一直觉得“大概会了”,结果一做题就卡在安全序列的更新上。从那以后我每次复习计算题都强制走一遍手算流程,不跳步。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进