操作系统
《操作系统》全课程精讲
一、引言
操作系统是计算机系统里最"忙"的那个角色:CPU 忙、内存忙、磁盘忙、键盘鼠标忙,而它负责让这一切"忙而不乱"。
学这门课之前你可能觉得操作系统就是 Windows / Linux / macOS 的图标和窗口;学完之后你会发现,它其实是一套资源管理的艺术——怎么把稀缺的硬件资源分给众多进程,怎么让它们互相协作而不是互相踩踏,怎么在"性能"和"安全"之间找平衡。
本笔记按"一条主线 → 逐章精讲 → 全书收尾"的脉络来写,每一章都回答四个问题:这一章在干什么?核心机制怎么设计?考试考什么?为什么重要?
跟着这条主线走,整门课就串成了一张网,而不是八个孤立的知识点。
二、一条主线:操作系统就是资源管理器
先记住一句话:操作系统 = 资源管理器 + 并发发动机。
整门课的骨架是四类资源:CPU(进程与调度)、内存(内存管理)、外存(文件系统)、I/O 设备(设备管理)。每类资源的管理都要解决同一个三板斧问题:
- 怎么抽象——把冰冷的硬件封装成好用的接口(把磁盘抽象成文件、把内存抽象成地址空间、把 CPU 抽象成进程)。
- 怎么复用——多个程序怎么共享这块资源(分时复用 CPU、分空间复用内存、交替复用磁盘)。
- 怎么隔离与保护——一个程序出错了,凭什么不拖垮别人?(进程地址空间隔离、特权级与中断)。
而这一切的背后,灵魂只有两个字:并发。单道程序很简单,逐条执行就行;一旦引入多道程序"同时"运行,所有问题都来了——谁先跑、跑多久、资源够不够分、互相干扰怎么办、两个进程都想要同一把椅子会不会僵死。于是整门课的每个章节,其实都是在回答同一个问题:
"这个资源怎么抽象、怎么分配、怎么回收、冲突了怎么办?"
把这条主线套到各章:
- 进程与线程 = 把 CPU 抽象成"进程"这个实体,它是资源分配和独立调度的单位;
- 调度 = 多个进程抢 CPU 时,谁来用、用多久;
- 同步互斥 = 多个进程抢同一份数据/资源时,怎么协作、怎么避免互相破坏;
- 死锁 = 谁都不肯让,大家一起堵死,怎么预防、怎么绕开、怎么救;
- 内存管理 + 虚拟内存 = 物理内存不够用,怎么抽象出"虚拟地址空间"这个假象;
- 文件系统 = 把磁盘一堆 0/1 抽象成"文件/目录"这棵看得见的树;
- 设备管理 = 把五花八门的硬件抽象成统一接口,并用 SPOOLing / 缓冲来提升性能。
这里把四个核心抽象点破一下,它们就是主线的"结晶":
- 进程:正在运行的程序(运行中的程序 + 它的状态与资源),是 CPU 的抽象,也是资源分配的基本单位。
- 线程:进程内部的"轻量级执行流",是 CPU 调度的基本单位;同一进程的线程共享地址空间,切换开销远小于进程。
- 文件:外存的抽象,用户眼中"有名字的逻辑数据集合",与磁盘上的物理存储位置解耦。
- 虚拟内存:把物理内存抽象成"连续、巨大的逻辑地址空间",让程序以为内存无限大,靠请求分页 + 页面置换实现。
记死这条主线,后面所有章节都是它的展开。
三、逐章精讲
第 1 章 操作系统概述
这一章在干什么
万事开头难。第一章其实在做两件事:定义操作系统是什么、有什么职责,以及从用户/程序的角度看,操作系统长什么样(也就是它提供了哪些接口,硬件和上层怎么衔接)。它是全书的地基——后续所有章讲的"资源管理",本质上都是第一章"操作系统目标与功能"的细化。
核心内容
1. 操作系统的目标与功能
目标:方便性、有效性(提高资源利用率与系统吞吐量)、可扩展性、开放性。
功能可以概括为一个管理 + 两大接口:
- 资源管理:处理机(进程)管理、存储器管理、文件管理、设备管理——就是主线的四类资源。
- 接口:命令接口(用户敲命令,在线 / 离线)、程序接口(即系统调用,程序员写代码时调用)、图形界面接口(GUI,本质上是命令接口的图形化)。
2. 发展历史(常考:各个阶段的驱动力)
| 阶段 | 特点 | 关键驱动力 |
|---|---|---|
| 手工阶段 | 人机矛盾,独占机器,机器等人 | 无操作系统 |
| 单道批处理 | 内存只放一道作业,自动转接,仍有人机矛盾 | 减少人工干预 |
| 多道批处理 | 内存放多道作业,CPU 与 I/O 交替运行,资源利用率大增 | 解决单道时 CPU 等待 I/O 的空转 |
| 分时系统 | 时间片轮转,多用户交互 | 满足交互性需求 |
| 实时系统 | 硬实时/软实时,截止时间必须满足 | 满足时间约束 |
记忆口诀:手工 → 单道批 → 多道批 → 分时 → 实时,核心驱动力是"人机矛盾 → CPU 等待 I/O → 交互需求 → 时间约束",一步步升级。
3. 操作系统结构(从复杂到可靠)
- 单体结构:所有功能揉成一个模块,性能好,但"牵一发动全身",难以维护(早期 UNIX、Linux 接近)。
- 模块化:按功能分成模块,接口调用。
- 微内核:内核只保留最必要功能(进程通信、中断、最基本调度),其余移入用户态进程;可靠性、可扩展性好,但性能略差(Windows NT 后期 / macOS 风格)。
- 外核:只负责硬件资源的分配与隔离,授权给库操作系统管理。
4. 系统调用、中断与异常(本考点)
这是第一章的重头戏,也是理解全书的钥匙,三者必须分清:
- 中断(Interrupt):来自 CPU 外部(I/O 设备等硬件),是"异步"的——CPU 正在执行某程序时被硬件打断。分可屏蔽中断和不可屏蔽中断(NMI)。
- 异常(Exception,也称内中断/陷入):来自 CPU 内部,执行指令时同步产生,比如除零、缺页、越界。其中由系统调用指令(trap 指令)主动触发的叫"陷入"。
- 系统调用:用户程序为了请求内核服务(打开文件、fork 进程等)而执行的一条特殊指令(如 x86 的
int 80h/syscall),通过陷入进入内核。它属于"异常"的一种,但目的不同——异常多半是被动的错误,系统调用是主动的求助。
中断处理的大致流程(填空/简答爱考):检测中断 → 关中断、保存断点(PC/PSW)与现场 → 识别中断源 → 转入对应的中断处理程序 → 恢复现场 → 开中断返回用户态。
特权级概念:内核运行在核心态(管态),用户程序运行在用户态(目态)。涉及资源管理的指令(如 I/O 指令、修改页表)只能在核心态执行,用户态通过系统调用"借道"完成——这是保护机制的第一道防线。
典型题型 / 考点
- 中断、异常、系统调用的区别与联系(最常考,尤其是"缺页属于异常还是中断")。
- 中断处理流程排序。
- 多道批处理与分时系统的特点对比(表格背熟)。
- 核心态与用户态、特权指令的判断。
- 操作系统四个基本特征:并发、共享、虚拟、异步(也常在这里考)。
为什么这一章重要
它是整张网的地基:中断/异常机制是第 2 章进程切换、第 6 章缺页中断、第 8 章设备中断的公共底层;系统调用是"用户态"和"核心态"的桥梁。这章概念不清,后面全部听天书。
第 2 章 进程与线程
这一章在干什么
第一章说"处理机管理",这一章就是它的主体:把"程序"升级成"进程"这个动态实体,让多个程序能并发执行;再进一步拆出"线程",把"资源分配"和"调度执行"两个职责分开。同时解决进程之间怎么通信(IPC)。这一章是全书戏份最重的章节之一,也是主线的起点。
核心内容
1. 进程的概念与状态转换
- 程序是静态的(一堆指令),进程是动态的(程序的一次执行过程,含状态、数据、PCB)。进程是资源分配的基本单位,具有动态性、并发性、独立性、异步性。
- 三态模型:就绪(Ready,万事俱备只欠 CPU)、运行(Running)、阻塞(Blocked,等待某事件,如 I/O 完成)。
- 状态转换图(必背):
- 就绪 → 运行:被调度(获得 CPU);
- 运行 → 就绪:时间片用完 或被更高优先级抢占;
- 运行 → 阻塞:主动请求某资源/事件(如等待 I/O);
- 阻塞 → 就绪:所等待的事件发生(如 I/O 完成)。
- 关键易错点:阻塞 → 运行 不存在(必须先经就绪再由调度);就绪 → 阻塞 也不存在。
- 五态/七态模型在基础上加"创建态、终止态"以及"挂起态(静止就绪/静止阻塞)",挂起是把进程调到外存,减轻内存压力——这正是第 6 章"中级调度/对换"的入口。
2. 进程控制块 PCB
PCB 是进程存在的唯一标志,系统就是靠它"认出"一个进程。内容分为四类:
- 进程标识符(内部 pid、外部名);
- 处理机状态(通用寄存器、程序计数器 PC、程序状态字 PSW、栈指针——用于上下文切换时保存/恢复现场);
- 进程调度信息(优先级、状态、等待的事件);
- 进程控制信息(内存指针、I/O 状态、记账信息)。
配套概念:进程的创建/终止(fork/exec、exit),上下文切换(切换进程 = 切换 PCB,保存旧现场、恢复新现场,这是调度最直接的"代价"来源,也是第 3 章各种开销讨论的根源)。
3. 线程与多线程模型
为什么引入线程?两个痛点:进程切换开销太大(要切换整个地址空间、Tcb 全部现场);进程内无法并行做事(一个进程内只能串行)。线程把二者解耦:
- 线程 = 进程内的一条执行流,共享进程的地址空间与资源,只拥有自己独立的 TCB(栈、寄存器、程序计数器)。
- 进程是资源分配单位,线程是CPU 调度(执行)单位。
- 一个进程内的线程切换不需要切地址空间,开销远小于进程切换;但一个线程崩溃可能导致整个进程崩溃(线程没有保护边界)。
多线程模型:多对一(多个用户线程映射到一个内核线程,用户态切换快,但一个线程阻塞全体阻塞)、一对一(每个用户线程对应一个内核线程,并发好但开销大)、多对多(兼顾二者)。
4. 进程通信 IPC(四种方式)
- 共享内存:最快的 IPC,双方直接读写同一块内存;但需要同步互斥机制配合(衔接第 4 章)。
- 消息传递:通过 send/receive 原语;分直接通信(指名道姓)与间接通信(通过邮箱/信箱),分同步(阻塞)与异步(非阻塞)。
- 管道:内核维护的一段环形缓冲区,数据先进先出。匿名管道只用于父子进程且单向;命名管道(FIFO)允许无关进程通信。管道是"半双工"的,且容量有限,写满阻塞、读空阻塞——这是它的同步语义。
- 信号(Signal):软件层面的异步通知机制,进程收到信号可忽略、捕获处理或按默认方式终止,多用于异常/事件的通告(如 Ctrl+C、段错误)。
典型题型 / 考点
- 三态/五态状态转换图辨析(给场景判断状态转换是否合法)。
- PCB 包含哪些内容;进程切换要做哪些事。
- 进程与线程的对比表格(资源、调度单位、地址空间、切换开销、独立性、崩溃影响)。
- 匿名管道与命名管道的区别;管道是单向还是双向。
- 共享内存与消息传递的优劣。
为什么这一章重要
它是"并发"主线的第一个正式战场。PCB 是"进程"抽象的物质基础,状态转换是调度(第 3 章)的前提,同步互斥(第 4 章)解决的正是进程共享资源时的冲突——第 3、4 章全是第 2 章的续篇。
第 3 章 处理机调度
这一章在干什么
多个进程都"就绪"了,CPU 只有一个,给谁用?用多久?这就是处理机调度。前面说 PCB 里有"调度信息",这一章就是教你怎么用它做决策,并且用一堆"性能指标"来评判你的决策好不好。调度算法是全书最"能算"的章节之一,属于送分题但要细心。
核心内容
1. 调度层次
- 高级调度(作业调度/长程):决定哪个作业从外存后备队列进入内存(调多少、调哪个)。
- 中级调度(内存调度):对换,决定进程在外存与内存之间对换(涉及挂起)。
- 低级调度(进程调度/短程):决定就绪队列中哪个进程获得 CPU,最频繁、最核心。
2. 调度准则(评价指标,全要背)
- CPU 利用率 = CPU 忙的时间 / 总时间,越高越好。
- 系统吞吐量 = 单位时间完成的作业数,越高越好。
- 周转时间 = 完成时刻 − 到达时刻,越小越好;带权周转时间 = 周转时间 / 运行时间,越接近 1 越好(这个最公平,特别爱考)。
- 等待时间 = 等待 CPU 的时间总和。
- 响应时间:从提交请求到首次响应,交互系统重点关注。
注意:批处理系统重"吞吐量与周转",分时系统重"响应时间",实时系统重"截止时间"。
3. 五大经典算法(重点)
- 先来先服务 FCFS:按到达先后排队,非抢占。实现简单、公平,但对短作业极不友好——一个长作业在前面,短作业全堵车(护航效应),平均周转时间可能很差。
- 短作业优先 SJF / 短剩余时间优先 SRTF:谁运行时间短谁先(SJF 非抢占,SRTF 抢占)。平均周转时间理论上最短,但无法预知运行时间(只能估计)、长作业可能"饿死"(活活等不到执行)。
- 时间片轮转 RR:就绪队列按 FCFS 排队,每个进程只跑一个时间片 q,到点回队尾。q 太大退化成 FCFS,q 太小则切换开销飙升。分时系统的代表,保证每个进程都能"轮上",响应性好。
- 优先级调度:高优先级先执行,可分抢占/非抢占。问题:低优先级可能饿死,需要老化(aging)技术——随着等待时间增加逐步提高优先级。
- 多级反馈队列 MLFQ:综合之王。多条优先级队列,从上到下时间片递增(如 1、2、4、8),新进程先进最高优先级队列,时间片没用完就提前结束则升级,用完了则降级。兼顾短作业(反应快)、长作业(能跑完)与 I/O 型进程(主动让出 CPU 得优待),且不需要预先知道运行时间。这是实际操作系统(Linux/Windows)调度器的鼻祖,几乎必考。
典型题型 / 考点
- 大计算题:给进程(到达时间、服务时间),分别用 FCFS / SJF / SRTF / RR 计算各进程周转时间、平均周转时间、带权周转时间、平均带权周转时间。解题要列甘特图(Gantt chart),注意到达时间参差时 SJF 只能选"当前已到达"的进程。
- 判断某算法是抢占还是非抢占;抢占的条件。
- 多级反馈队列的运行过程模拟(几级、时间片多少、何时升级降级)。
- 问"哪个算法平均周转时间最短" → 答案 SJF/SRTF。
为什么这一章重要
它是"CPU 资源分配"问题的核心答案,直接决定系统的吞吐量和响应速度。主线里的"怎么分配"在这里得到第一个完整的数学化回答。同时,调度的开销分析(上下文切换成本)和第 2 章的线程设计互为因果。
第 4 章 进程同步与互斥
这一章在干什么
进程可以并发了,麻烦来了:两个进程同时往同一个变量里写、同时读同一块共享内存,结果对不上账(竞态条件)。这一章解决"进程间怎么协作、怎么防打架"的问题——前半部分教"怎么互斥地访问共享资源(临界区)",后半部分教"怎么按正确的先后顺序协作(同步)"。信号量/管程是实现手段,经典问题是最好的练习题。
核心内容
1. 临界区与三个原则
- 临界资源:一次只允许一个进程使用的资源(打印机、共享变量)。
- 临界区:访问临界资源的那段代码。
- 正确进入临界区必须满足三个原则(背!):互斥(一个进程在临界区,其他想进的不许进)、前进(临界区空闲时,应让一个进程进去,不能无限拖延)、有限等待(等待者最终必须能进入,不许饿死)。
2. 软件与硬件实现
- 软件:单标志法(违背"空闲让进")、双标志先检查(违背"忙则等待",有并发空隙)、双标志后检查(违背"有限等待",可能互相谦让死锁)、Peterson 算法(先举手再让路,满足全部三原则,但存在复杂缺陷,且忙等浪费 CPU)。
- 硬件:中断屏蔽(简单粗暴,但特权指令、多 CPU 无效)、TestAndSet / Swap 原子指令(利用硬件原子性实现"忙等"的锁)。硬件法优点是适用于多处理器,缺点是忙等浪费 CPU、可能饥饿。
3. 信号量(本课最核心的同步工具)
信号量是一个整数变量 + P/V 操作(down/wait 与 up/signal,Linux 中 sem_wait/sem_post)。P/V 必须是原子操作。
- 整型信号量:P 用 while 忙等,浪费 CPU。
- 记录型信号量:value + 等待队列。P(wait):value--,若小于 0 则阻塞入队;V(signal):value++,若小于等于 0 则唤醒队首。阻塞而不是忙等,这才是现代实现。注意:P 表示"申请一个资源",V 表示"释放一个资源",而 value 的初值 = 可用资源数。
用信号量实现互斥:初值 1,每个临界区前后各加 P、V——经典考题。
用信号量实现同步:例如"必须先做 A 再做 B",信号量初值 0,A 之后 V,B 之前 P——通过"谁给谁发许可"来控制顺序。初值定错顺序就全错,这是爱考的点。
4. 管程(Monitor)
信号量的问题:P/V 分散在各进程中,写错一个就全盘崩。管程把共享数据和操作它的过程封装在一个模块里,保证"同一时刻只有一个进程在管程内",程序员不用手动 P/V。管程里的条件变量配合 wait/signal 实现进程的等待与唤醒。它是对信号量的一次"面向对象式封装",更安全、更易写。
5. 经典同步问题(考试重灾区)
- 生产者-消费者:有界缓冲区,生产者放、消费者取,既要互斥(不能同时动缓冲区)又要同步(缓冲满则生产者等、缓冲空则消费者等)。用三个信号量:mutex=1、empty=n、full=0。注意 P 操作的顺序:必须先 P(empty/full) 再 P(mutex),反了可能死锁。
- 读者-写者:允许多个读者同时读,但写者独占。用 readcount 计数 + mutex 保护 readcount + rw 信号量控制读写。分读者优先(读者连续来则写者可能饿死)和写者优先两类考法。
- 哲学家进餐:5 个哲学家、5 根筷子,每人需要两根筷子才能吃。朴素解法(先拿左再拿右)可能导致死锁(大家都拿了左边)。解决办法:最多 4 人同时拿筷子;先取两边都空的筷子;给筷子编号拿小号先拿。考核点就是"死锁的成因与如何用信号量避免"。
典型题型 / 考点
- 给场景,用信号量写出正确的 PV 操作(包括初始化信号量、初值解释)——大题最热门。
- 分析某段 PV 操作错误会引发什么问题(死锁/破坏互斥/破坏同步)。
- 经典三问题的分析:是否需要互斥、需要几个信号量、顺序是什么。
- 临界区三原则、软件/硬件方法的优缺点对比。
- 管程与信号量的区别。
为什么这一章重要
"冲突了怎么办"在这里得到正式回答。同步与互斥是并发编程的灵魂,也是死锁(第 5 章)的前提——因为死锁正是同步互斥机制用错了的恶果。生产者消费者等模型也被延伸到文件系统、设备管理(缓冲区、SPOOLing)中反复出现。
第 5 章 死锁
这一章在干什么
进程们互不相让,你等我的资源、我等你的资源,一起僵住谁也不干活——这就是死锁。这一章研究:死锁怎么产生的?怎么提前预防(不让条件成立)?怎么动态避免(算法实时判断)?以及真死了怎么检测、怎么救活?银行家算法是本章的招牌计算题。
核心内容
1. 死锁的定义与四个必要条件(必背)
一组进程互相等待对方占有的资源而永远阻塞,称为死锁。四个必要条件缺一不可:
- 互斥:资源一次只能被一个进程占用;
- 占有并等待:进程占着资源又在等别的资源;
- 不可剥夺:已被占有的资源不能强抢,只能等持有者主动释放;
- 循环等待:存在一个"你等我、我等你"的等待环路。
2. 预防死锁(破坏四个条件)
- 破坏互斥:不可能(这是资源固有属性);
- 破坏占有并等待:一次性申请所有资源(资源预分配),但资源利用率低、可能饿死;
- 破坏不可剥夺:可抢占,实现复杂;
- 破坏循环等待:给资源编号,必须按编号升序申请,破除环路。
3. 避免死锁——银行家算法(计算题)
- 基本思想:资源分配前,先判断系统是否仍处于"安全状态";只有安全才分配。安全状态 = 存在一个安全序列,按此顺序执行,每个进程都能在现有+回收的资源下完成。
- 数据结构:
Available(各类资源可用量)、Max(每个进程最多需要)、Allocation(已分配)、Need = Max − Allocation(还需要)。 - 算法步骤:① 检查请求 Request ≤ Need 且 ≤ Available;② 试探性分配(Available -= Request,Allocation += Request,Need -= Request);③ 用安全性算法找安全序列:找 Need ≤ Work 的进程,Work += Allocation,循环,直到所有进程都能完成 → 安全则真分配,否则撤销试探,拒绝请求(回滚)。
- 银行家算法前提是事先知道每个进程的最大需求,现实中很难满足,所以更多是教学意义,但考试必考。
4. 死锁的检测与解除
- 资源分配图:圆 = 进程,方框 = 资源类,圆点 = 实例,有向边 = 请求/分配。
- 死锁定理:S 为死锁状态的充要条件是资源分配图不可完全简化(把所有能执行的进程依次拿掉资源后,图里还有进程拿不到全部需求 → 死锁)。
- 解除:资源剥夺(抢一个进程的资源给别的)、撤销进程(一次性撤销/逐个撤销直到解除)、进程回退(到安全点重跑)。被选中的牺牲者一般是优先级低、已运行时间少、执行时长大的进程。
典型题型 / 考点
- 银行家算法大题:给 Allocation、Max、Available,判断某请求是否可满足、写安全序列、说明安全/不安全。步骤务必写全:Need 表 → 试探分配 → 安全性检测 → 结论。
- 判断给定资源分配图是否死锁(化简图)。
- 四个必要条件的判断与破坏方法对应。
- 预防、避免、检测、解除四类方法的区别与适用场景(表格)。
为什么这一章重要
死锁是并发系统最经典的"事故",也是资源分配问题的极端情形。主线里"冲突了怎么办"在这一章达到最高潮——从前面的"尽量避免冲突"升级到"冲突不可调和时的救火方案"。银行家算法是全书少数"完整算法题"之一,性价比极高。
第 6 章 内存管理
这一章在干什么
程序要跑,就必须驻留内存。这一章解决:程序在内存里怎么放(连续/分页/分段)、地址怎么翻译(地址变换 + TLB)、物理内存不够了怎么办(虚拟内存 + 页面置换)。本章计算题多、概念密度大,是全书的重头戏。
核心内容
1. 连续分配管理方式
- 单一连续分配:内存只放一道程序,简单但利用率低(变成"单道"了)。
- 固定分区分配:内存切成若干固定分区,一张分区说明表记录使用情况。缺点:分区大小固定,大作业装不下、小作业浪费(内部碎片)。
- 动态分区分配:按需分配大小,有外部碎片,需要紧凑技术。分配算法:首次适应(找第一个能装下的,快、优先用低地址)、最佳适应(找最小能装下的,产生最多小碎片)、最坏适应(找最大的,碎片小但大块全切没了)。动态分区要解决:空闲分区表/链表 + 分区的分配与回收(回收时注意相邻空闲区合并)。
2. 分页存储管理
- 思路:把程序逻辑地址空间切成页(Page,如 4KB),物理内存切成等大的页框(帧,Frame),页可以放在任意页框里 → 消除外部碎片,只有页内不超过半页的内部碎片。
- 页表:页号 → 页框号 的映射表。地址结构 = 页号 + 页内偏移量;偏移量位数由页大小决定(4KB → 低 12 位是偏移)。地址变换:逻辑地址 → 找页表项 → 得物理页框号 + 页内偏移 = 物理地址。
- 快表 TLB:页表在内存里,每次访存要先查表(多一次访存)再取数(再访存),共两次。用快表(寄存器/缓存)存最近用过的页表项,命中则一次访存搞定——TLB 命中率是性能关键。
- 页表太大怎么办:两级页表/多级页表(页目录 + 页表),按需加载页表页;现代 CPU 还有 倒置页表。
3. 分段与段页式
- 分段:按程序逻辑划分(代码段、数据段、栈段),段大小可变,每段独立连续。好处:便于共享、便于保护、符合程序员思维;缺点:有外部碎片、段长不固定。
- 分段 vs 分页:分页是物理单位(透明、固定、无逻辑含义),分段是逻辑单位(可见、可变、有含义)。分页消除外部碎片、分段方便共享。
- 段页式:先分段再分页,寻址三部分:段号 + 页号 + 页内偏移,先查段表得页表基址,再查页表得页框。集中二者优点,但多一次访存(同样需要 TLB 弥补)。
4. 虚拟内存与请求分页(本章精华)
- 局部性原理:时间局部性(刚用过的地址马上还会用)+ 空间局部性(用过的地址附近的也会用)。虚拟内存就是建立在局部性之上:程序只需要部分页面在内存就能运行。
- 虚拟内存特征:多次性(作业分多次调入)、对换性(换入换出)、虚拟性(逻辑上扩展内存)。
- 请求分页:进程装入部分页;访问缺页时触发缺页中断(属于异常!),从外存调入,若内存无空闲页框则先按置换算法换出一个页。缺页中断的处理流程:陷入 → 保存现场 → 查外存 → 调页 → 修改页表 → 恢复现场。
- 页面置换算法(必考计算):
- OPT(最佳):置换"将来最长时间不会被访问"的页。理论最优,但无法预知未来,只用来做评判标准。
- FIFO(先进先出):置换最早进入的页。简单,但有 Belady 异常(分配页框变多反而缺页变多)。
- LRU(最近最久未使用):置换最近最长时间没用过的页,利用局部性。性能接近 OPT,但实现开销大(栈/计数器)。
- CLOCK(时钟/第二次机会):环形链表 + 访问位,扫描时把访问位清 0,遇到 0 就置换;是 LRU 的近似,开销小,是实际系统主流。
5. 内存分配策略与抖动
- 固定分配局部置换 / 可变分配全局置换 等四种组合(背过即可)。
- 抖动(Thrashing):分配给进程的页框太少,刚换出去立刻又缺页,进程大部分时间都在换页,CPU 利用率暴跌。解决:工作集模型——保证进程的"工作集"(最近一段时间访问的页面集合)在内存中;缺页率过高时暂停部分进程(结合中级调度)。
- Belady 异常只可能出现在 FIFO(堆栈类算法如 LRU、OPT 没有)。
典型题型 / 考点
- 地址变换计算:给逻辑地址、页大小、页表,求物理地址(注意页内偏移位数;可能考段页式)。
- 缺页率计算:给访问串和页框数,分别用 OPT/FIFO/LRU/CLOCK 算缺页次数(画表!)。注意"开始时内存空的算不算缺页"——一般算,题目要说清楚。
- Belady 异常的判断题。
- 内部碎片 vs 外部碎片;固定/动态分区与分页分段的对比。
- 请求分页与虚拟内存的概念辨析;局部性原理。
为什么这一章重要
内存是最稀缺的资源,这一章完整呈现了"抽象(虚拟地址空间)+ 复用(分页共享内存)+ 隔离(页表保护)+ 缺页处理(异常机制的实战)"的主线闭环。分页 + 虚拟内存 + LRU 是整个操作系统考研/期末的超级重点,几乎年年出计算题。
第 7 章 文件管理
这一章在干什么
前面管 CPU、管内存,现在管外存(磁盘)。这一章把磁盘上一堆扇区抽象成用户友好的"文件 + 目录树",并解决三个问题:文件内部怎么组织(逻辑结构)、文件怎么存在磁盘上(物理结构)、空闲磁盘空间怎么管理(位示图等),最后讲磁盘的读速度优化——磁盘调度。这一章偏概念 + 简单计算,是拿分章。
核心内容
1. 文件与文件系统
- 文件:以文件名标识的、有逻辑意义的字节序列,是外存的抽象。
- 文件属性:文件名、标识符、类型、位置、大小、时间、权限。
- 文件系统:负责文件的建立、读写、删除、目录管理与存储空间管理。
- 文件的逻辑结构:无结构(字节流)、顺序结构(记录定长/变长)、索引结构(按索引快速查)。
2. 文件在磁盘上的物理结构(FCB/索引)
- FCB(文件控制块) = 文件在磁盘上的"身份证",含全部文件属性;目录就是 FCB 的集合。
- 物理分配方式(核心):
- 连续分配:文件占连续磁盘块。顺序读写快,但难以动态增长、有外部碎片。
- 链接分配:隐式链接(每个块存下一块的指针,顺序访问慢、指针占空间、一个块坏整链断);显式链接(FAT 表)——把指针集中到一张文件分配表,访问任意块只需查 FAT,Windows 的老底子。
- 索引分配:为每个文件建索引块,块号数组直接定位任意块,支持随机访问;大文件用多级索引 / 混合索引(UNIX:直接块 + 一级/二级/三级间接,经典计算题——给定块大小与盘块号位数算最大文件长度)。
- 三种方式的对比(顺序/随机访问能力、动态增长、碎片)是常考点。
3. 目录结构
- 单级目录:全放一个目录,命名冲突。
- 两级目录:主目录 + 用户目录,解决用户间冲突。
- 树形目录(多级):路径名解析(绝对路径/相对路径),支持文件的共享与保护,现代系统标配。
- 无环图目录:在树上加"链接",实现共享(用硬链接/软链接实现)。注意处理循环与计数问题。
4. 文件存储空间管理(空闲块怎么管)
- 空闲表法:记录连续空闲区,适合连续分配。
- 空闲链表法:空闲块链(块链:每块指下一块)或空闲区链。
- 位示图法(重点):用一串二进制位表示磁盘块是否空闲。经典计算:位示图需要多少字、某块号对应的字号/位号、由(i,j)反推盘块号——公式题必练。
- 成组链接法:UNIX 用的,把空闲块分组管理,适合大磁盘、支持大文件的快速分配。
5. 磁盘调度(计算题重头)
磁盘访问时间 = 寻道时间(大头)+ 旋转延迟 + 传输时间,所以调度优化主要优化磁头移动(寻道)。
- FCFS:按请求顺序服务,公平但寻道距离大。
- SSTF(最短寻道优先):总是先服务离当前磁头最近的,寻道短但可能饥饿(远处请求饿死)。
- SCAN(电梯算法):磁头向一个方向移动,一路上顺路服务,到头再反向。不会饿死,但"边缘"请求等待久;LOOK 是改进:不走到头,最远请求即反向。
- C-SCAN(循环扫描):单向服务,返回时直接快速回到起点不服务,等待更均匀。
- 计算题型:给磁头当前位置 + 请求序列,画磁头移动轨迹,求总寻道距离。注意题目用 SCAN 还是 LOOK、起始方向。
典型题型 / 考点
- 磁盘调度大计算题(FCFS/SSTF/SCAN/C-SCAN 的寻道距离)。
- 位示图:由盘块号算字号位号、由字号位号算盘块号。
- 混合索引 / 多级索引最大文件长度计算。
- 连续、链接、索引三种分配方式对比。
- 树形目录与路径、硬链接/软链接的区别。
为什么这一章重要
它完成了"外存资源管理"这一主线模块。前面的进程/内存讲的是"运行时的世界",这一章讲的是"断电后怎么保存"——文件和磁盘调度的优化(减少寻道)正是"复用磁盘这个慢速资源"性能考量的体现。与第 6 章的页面置换算法互相呼应(都是"资源不够/访问太慢时如何换入换出")。
第 8 章 输入输出管理
这一章在干什么
最后一类资源:五花八门的 I/O 设备。这一章解决:CPU 怎么跟设备打交道(查询/中断/DMA)、软件怎么把设备抽象成统一接口(I/O 软件层次)、慢速设备怎么伪装成高速(SPOOLing)、速度不匹配怎么缓解(缓冲)、设备怎么分配。它是前几章所有机制的"总应用",综合性最强。
核心内容
1. 设备与控制器
- I/O 设备分类:按使用特性(人机交互/存储/网络通信)、按传输速率(低速/中速/高速)、按信息交换单位(块设备如磁盘、字符设备如键盘)。
- I/O 控制器(设备控制器):CPU 不直接操作设备,而是通过控制器(含控制寄存器、状态寄存器、数据寄存器和I/O 接口逻辑),CPU 通过端口/寄存器与控制器打交道。控制器里的数据缓冲寄存器负责速度匹配,状态寄存器报告设备忙闲。
2. 四种 I/O 控制方式(演进史)
- 程序直接控制(查询方式):CPU 不断循环查状态寄存器,忙等,CPU 被完全拖死——最浪费。
- 中断驱动方式:CPU 发出命令后去干别的,设备完成时发中断通知 CPU。解决了等待浪费,但每传一个字节都要中断一次,中断开销大。
- DMA 方式(直接存储器存取):DMA 控制器直接在外存与内存之间批量搬运数据(按块传),传送过程不占 CPU,只在整块传完发一次中断。需要内存地址寄存器、数据计数寄存器、传送方向等。这是高速块设备(磁盘、网卡)的标准方式。
- 通道方式:更高级,专门的 I/O 处理器可执行"通道程序"控制多台设备,一次处理多块。中断次数进一步减少。
易考点:中断驱动与 DMA 的区别——中断是"每传一个字节中断一次",DMA 是"一整块传完才中断一次",且 DMA 期间 CPU 可并行做事。
3. I/O 软件层次(自顶向下)
- 用户层 I/O 软件:系统调用、格式化、spooling 等(发出请求)。
- 设备独立性软件:统一接口(open/read/write/close)、设备命名与重定向、错误报告、设备分配与回收、缓冲管理。
- 设备驱动程序:每个设备一个,把上层的统一请求翻译成该设备控制器的具体命令——设备无关性正是靠驱动层隔离实现的。
- 中断处理程序:处理设备中断,真正完成数据搬运与响应。
4. 假脱机 SPOOLing(打印机虚拟化)
- 问题:打印机是独占设备,谁用谁独占,慢、利用率低。
- 方案:用输入井/输出井(磁盘上的缓冲区) + 输入/输出进程,把独占的打印机变成"逻辑上可以共享的虚拟设备"。
- 原理:进程把要打印的内容先写进输出井(这一瞬间是快的、不独占打印机),再由 SPOOLing 进程排队统一打印。用户感觉"我直接打印成功了",实际是"假打印"(提交到输出井)。
- 结论:SPOOLing 实现了虚拟设备,把独占设备转化为共享设备,缓解了"谁拿打印机谁独占"的矛盾。
5. 缓冲技术(速度匹配 + 数据就绪)
- 作用:缓解 CPU 与设备速度不匹配、减少中断次数、缓冲数据的读写单元不匹配、提高并行性。
- 类型:单缓冲 / 双缓冲(双倍率周转)/ 循环缓冲(多个缓冲,消费生产交替)/ 缓冲池(系统级公用)。注意单/双缓冲计算传输时间的经典小计算(谁可以和谁并行)。
- 缓冲 vs 缓存:缓冲缓冲"速度不匹配 + 数据就绪"(纯暂存),缓存缓存"内容复用"(存一份留用),性质不同,常对比考。
6. 设备分配
- 分配原则:独占设备(独占方式)、共享设备(共享方式)、虚拟设备(SPOOLing 方式)。
- 设备独立性:进程用逻辑设备名申请,由系统映射到物理设备 → 提升灵活性。
- 数据结构:设备控制表 DCT、控制器控制表 COCT、通道控制表 CHCT、系统设备表 SDT;分配顺序:进程 → 通道 → 控制器 → 设备(注意死锁避免:一次分配所有资源或按序分配——这里又回到了第 5 章的思想)。
典型题型 / 考点
- 中断驱动与 DMA 的区别;DMA 工作过程。
- SPOOLing 为什么能把独占设备变共享设备;打印过程描述。
- 缓冲的作用;单/双缓冲计算。
- I/O 软件层次的功能划分;设备无关性的实现。
- 设备分配中的安全思想(防止分配死锁)。
为什么这一章重要
它把全书机制做了一次大阅兵:中断(第 1 章)在这里直接支撑 I/O 控制,缓冲与生产者-消费者(第 4 章)在缓冲池中再现,SPOOLing 是对"复用 + 抽象"的完美演绎,设备分配的防死锁(第 5 章)思想再次落地。I/O 往往考概念辨析,但每一条都能和主线挂钩,复习时注意串联。
四、全书收尾:资源管理全景图
把主线画成一张图,全书就尽收眼底:
┌──────────────────────────────────────────────┐
│ 用户进程 / 线程(系统调用接口) │
└───────────────┬──────────────┬────────────────┘
┌───────────────────────┼──────────────┼───────────────────────┐
│ │ │ │
┌─────────▼─────┐ ┌─────────▼─────┐ ┌──────▼──────┐ ┌──────────▼──────┐
│ CPU 管理 │ │ 内存管理 │ │ 外存管理 │ │ I/O 设备管理 │
│ 进程/线程 │ │ 分页/分段 │ │ 文件系统 │ │ 设备独立层/驱动 │
│ 调度算法 │ │ 虚拟内存 │ │ 目录/位示图 │ │ 中断/DMA/缓冲 │
│ 同步互斥 │◄────►│ 页面置换 │ │ 磁盘调度 │◄────►│ SPOOLing │
│ 死锁/银行家 │ │ 抖动/工作集 │ │ 连续/索引分配 │ │ 设备分配 │
└─────────┬─────┘ └─────────┬─────┘ └──────┬──────┘ └──────────┬──────┘
│ │ │ │
└───────────┬───────────┴──────────────┴───────────────────────┘
▼
┌──────────────────────────────────────┐
│ 三件套:抽象(接口)· 复用(共享)· 保护(隔离) │
│ 灵魂:并发 —— 每个资源都在回答同一问题: │
│ 怎么抽象?怎么分配?怎么回收?冲突怎么办? │
└──────────────────────────────────────┘
几句话总结全书逻辑:
操作系统是资源管理器,四类资源(CPU / 内存 / 外存 / I/O)各有一章,但解题套路完全一致:先抽象出统一模型(进程、虚拟地址空间、文件、设备接口),再研究分配策略(调度、页面置换、目录与位示图、SPOOLing 与缓冲),再考虑冲突与保护(同步互斥、死锁、特权级、地址空间隔离)。底层由中断/异常/系统调用这张"事件网络"把用户态与核心态贯通起来。
复习权重建议(按期末/考研的惯例):
- 第 4 章(信号量 + 经典问题) ★★★★★:PV 操作大题必考,写代码刷起来。
- 第 6 章(分页 + 虚拟内存 + 置换算法) ★★★★★:地址变换、缺页率计算年年见,LRU/FIFO/OPT 算到滚瓜烂熟。
- 第 5 章(死锁 + 银行家算法) ★★★★☆:计算题型固定,按步骤写就是送分。
- 第 3 章(调度算法) ★★★★☆:周转时间计算,画甘特图细心即可。
- 第 7 章(文件 + 磁盘调度) ★★★☆☆:磁盘寻道距离、位示图,公式套用。
- 第 2 章(进程线程) ★★★☆☆:概念辨析为主,配合第 4 章一起复习。
- 第 1 章、第 8 章 ★★★☆☆:概念与辨析题,靠背诵 + 和主线串联理解。
最后一句忠告:不要一章一章孤立地背。合上书,把上面那张全景图自己在纸上默画一遍,能画出"每个资源 → 它的抽象 → 它的分配 → 它的冲突处理",这门课你就真正学通了。祝考试顺利!

浙公网安备 33010602011771号