操作系统 10|磁盘
第一次做 2015 年第 32 题,我把 SCAN 的磁头移动数算成了 287——因为我忘了磁头是「从外侧向内侧」移动,把方向搞反了。
磁盘调度这类题,公式不难,难在画对那条轨迹。方向、端点、要不要回绕,三个细节错一个,四个选项里总有一个数字在等你。这篇就把这四个算法拆到「拿笔就能画」的程度。
第〇节 · 扫盲(一句人话)
磁盘慢,不是因为「传得慢」,而是因为「找得慢」。
打个比方:磁盘像一个巨大的圆形仓库,数据按「圆环(磁道)→ 圆环上的格子(扇区)」摆放。要取一件货,机械臂(磁头)得先跑到对的圆环(寻道),再等仓库转到对的格子(旋转),最后才把货搬出来(传输)。前两步纯机械,毫秒级;最后一步电子级,微秒级。
所以磁盘调度的全部聪明,都是让机械臂少跑路——把一堆请求排序,顺路一次取完。
一、磁盘物理结构:盘面、柱面、磁道、扇区
一块硬盘由多个盘片同轴叠成,每个盘片两个记录面,每面一个磁头。
| 概念 | 含义 | 编号习惯 |
|---|---|---|
| 盘面 | 一个记录面 | 从上往下 0 开始 |
| 磁道 | 盘面上的同心圆 | 最外圈为 0 |
| 柱面 | 所有盘面同一半径的磁道集合 | 与磁道号同步 |
| 扇区 | 磁道被分成的弧段,最小读写单位 | 从 1 开始 |
⚠️ 扇区号从 1 开始(柱面号、磁头号从 0 开始)。这是 2013 年真题的命题陷阱,写地址时别顺手写成 0。
磁盘地址用 CHS 三元组表示:柱面号 Cylinder + 磁头号 Head + 扇区号 Sector。这个地址由设备驱动程序算出来(OS09 考过:算 CHS 是驱动层的事)。
为什么按柱面而不是按盘面组织?因为换柱面要寻道,换磁头不用。同一柱面上的数据,磁头切换是电子的,几乎不花时间——所以文件系统尽量把相关的块放在同一柱面。
二、容量公式与地址计算
磁盘容量 = 盘面数 × 每面磁道数 × 每道扇区数 × 扇区大小
再记两个推论:
-
一个柱面的容量 = 盘面数 × 每道扇区数 × 扇区大小;
-
按 CHS 编址,若柱面数 C、磁头数 H、每道扇区数 S,则总扇区数 = C × H × S,某个三元组的线性扇区号 = ((柱面号 × H) + 磁头号) × S + (扇区号 − 1)。
那个「−1」就是扇区从 1 开始的代价。
举个具体例子把公式用热:某盘 8 个盘面、每面 1024 个磁道、每道 64 个扇区、扇区 512B,求容量与 CHS = (100, 3, 1) 的线性扇区号。
-
容量 = 8 × 1024 × 64 × 512B = 256MB;
-
线性号 = ((100 × 8) + 3) × 64 + (1 − 1) = 803 × 64 = 51392。
注意这里乘的是「盘面数 8」,也就是每柱面 8 个磁道。柱面优先的编址方式决定了:磁头换面不用寻道,所以线性号连续的一段正好落在同一柱面上——这也是文件系统「尽量把同一个文件的块放在同一柱面」的物理依据。
三、访问时间三段式
存取时间 = 寻道时间 Ts + 旋转延迟 Tr + 传输时间 Tt
-
寻道时间 Ts:磁头移到目标磁道。机械动作,通常 3~10ms,占绝对大头;
-
旋转延迟 Tr:等目标扇区转到磁头下。平均按半圈算:Tr = ½ × (60 / 转速),转速单位 r/min;
-
传输时间 Tt:数据真正读出的时间。Tt = 数据量 ÷ 传输率,而传输率 = 每道字节数 × (转速/60)。
一个完整的算例
7200 r/min、平均寻道 5ms、每道 500 扇区 × 512B,读 4KB:
-
转一圈 = 60 / 7200 s ≈ 8.33ms;
-
平均旋转延迟 = 8.33 / 2 ≈ 4.17ms;
-
传输率 = 500 × 512 × (7200/60) ≈ 30.72MB/s;
-
读 4KB 的传输时间 = 4KB ÷ 30.72MB/s ≈ 0.133ms(等价于 8/500 圈 × 8.33ms);
-
总时间 ≈ 5 + 4.17 + 0.133 ≈ 9.30ms。
看一眼时间占比就明白了:机械两段占了 98% 以上。这就是「磁盘优化只优化寻道」的全部理由。
换一组数:随机 vs 顺序的差距有多大
同样 7200r/min、平均寻道 5ms 的盘,读 1MB 数据:
-
顺序读(连续 256 个 4KB 块,同一磁道附近):寻道按 1 次算 5ms,旋转 4.17ms,传输 1MB ÷ 30.72MB/s ≈ 32.6ms,合计约 42ms;
-
随机读(256 个分散的 4KB 块):每块都要 5 + 4.17 + 0.13 ≈ 9.3ms,合计约 2381ms。
差了 56 倍。这个倍数就是「数据库为什么怕随机 I/O」「日志为什么坚持顺序写」「SSD 为什么能碾压机械盘」的定量答案。做题时看到「顺序/连续」两个字,条件反射就该想到「寻道和旋转可以被摊薄」。
—— 访问时间三段式与机械/电子时间占比
四、为什么磁盘调度只优化寻道
三个时间段的性质完全不同:
| 时间段 | 性质 | 能否靠调度优化 |
|---|---|---|
| 寻道时间 | 机械移动,可改变顺序 | ✅ 能(这就是磁盘调度) |
| 旋转延迟 | 转速固定,等半圈 | ❌ 单次改不了(只能靠扇区交叉编号等布局手段摊薄) |
| 传输时间 | 由数据量和传输率决定 | ❌ 改不了(缓冲区合并能减少次数,但单次不变) |
所以四种调度算法全都只干一件事:给请求重新排序,让磁头总移动距离最短。
那旋转延迟就完全没办法了?也不是,只是不归「调度」管,归「布局」管:
-
扇区交叉编号(交错因子):把逻辑上连续的扇区在物理上隔开几个位置编号。因为读完一个扇区后,控制器需要一点处理时间,等它准备好,下一个物理扇区可能已经转过去了——交错编号让「下一个逻辑扇区」正好在磁头下。
-
柱面优先分配:同一文件的块先填满同一柱面,再换柱面。换磁头是电子的(微秒级),换柱面是机械的(毫秒级)。
-
块簇化:把多个扇区打包成簇,一次读一大块,减少「等下一圈」的次数。
这三招都不改变单次访问的三段时间,而是让每次访问尽可能落在「已经转到位」的位置——属于「布局优化」,和调度的「排序优化」互补。
五、四种调度算法总览
| 算法 | 规则 | 优点 | 缺点 |
|---|---|---|---|
| FCFS | 按请求到达顺序 | 公平、简单、绝不会饥饿 | 磁头乱跑,平均寻道差 |
| SSTF | 每次选离当前磁头最近的 | 平均寻道较好 | 可能饥饿 / 磁臂黏着 |
| SCAN(电梯) | 沿一个方向扫到头,再反向 | 无饥饿,性能好 | 两端磁道等待时间不均(刚扫过的端要等最久) |
| CSCAN(循环扫描) | 单向扫到一端,跳回另一端继续同向 | 更均匀,无饥饿 | 跳回那一下白跑,但可预测 |
一句话记:FCFS 公平但笨,SSTF 聪明但偏心,SCAN 是电梯,CSCAN 是只上不下的电梯。
为什么真实系统里 SSTF 反而用得少?因为它对「请求分布」极度敏感:请求密集时它表现很好,请求稀疏时它会在两端之间来回拉锯,而且只要有源源不断的近处请求,远处的请求就永远排不上。操作系统要保证的是最坏情况可忍受,不是「平均最好看」——SCAN 家族牺牲一点平均值,换来「任何请求的等待时间都有上界」,这才是工程上可接受的选择。这个思路在 CPU 调度里也出现过:SJF 平均周转最好,但会饿死长作业,所以真实系统用多级反馈队列。
再补一个教材差异,考试必须按 408 的口径:严格意义上的 SCAN 要扫到磁盘端点(0 或最大磁道号)才反向,而「扫到本方向最后一个请求就反向」的版本叫 LOOK。408 真题用的是 LOOK 口径——2009(29) 从 105 向增大方向走,服务完 195 就立刻回头,没有空跑到 199。所以做真题别套教科书的端点模型,按「最后一个请求」算,否则数字对不上选项。
六、同一序列,四种算法手算对照
请求序列:98、183、37、122、14、124、65、67,磁头当前在 53,磁道 0~199,初始向磁道号增大方向。
① FCFS:53 → 98 → 183 → 37 → 122 → 14 → 124 → 65 → 67
45 + 85 + 146 + 85 + 108 + 110 + 59 + 2 = 640 平均寻道长度 = 640 ÷ 8 = 80
② SSTF:53 → 65 → 67 → 37 → 14 → 98 → 122 → 124 → 183
12 + 2 + 30 + 23 + 84 + 24 + 2 + 59 = 236 平均寻道长度 = 236 ÷ 8 = 29.5
③ SCAN(向大扫到最后一个请求 183,再反向):
53 → 65 → 67 → 98 → 122 → 124 → 183 → 37 → 14 12 + 2 + 31 + 24 + 2 + 59 + 146 + 23 = 299 平均寻道长度 = 299 ÷ 8 = 37.375
④ CSCAN(向大扫到 183,跳回另一端最低请求 14,再向大):
53 → 65 → 67 → 98 → 122 → 124 → 183 →〔跳到 14〕→ 37 12 + 2 + 31 + 24 + 2 + 59 + 169 + 23 = 322 平均寻道长度 = 322 ÷ 8 = 40.25
四个数字 640 / 236 / 299 / 322 一摆,规律就出来了:SSTF 最省,但它有饥饿风险;SCAN 和 CSCAN 稍差,换来公平。
口径提醒:SCAN 我按「扫到本方向最后一个请求就反向」算(408 真题 2009(29) 就是这么算的,到 195 立刻回头,没有空跑到 199)。CSCAN 的跳回距离按「跳到另一端极值请求」算;有的教材按「跳到磁盘端点」算,数字会不同,以真题口径为准(见下面 2024(32))。
—— 四种调度算法的磁头轨迹对比
七、真题 2009(29):SCAN 的访问序列
磁头在 105 道,正向磁道号增加方向移动。请求序列 35、45、12、68、110、180、170、195,求 SCAN 的服务序列。
走法:先按增长方向服务所有大于 105 的请求,升序:110 → 170 → 180 → 195;然后反向,服务小于 105 的,降序:68 → 45 → 35 → 12。
答案 A:110,170,180,195,68,45,35,12。
陷阱在 B(110,68,45,35,12,170,180,195)——那是「看到最近的先服务」,是 SSTF 的思路;C 把反向段写成了升序,也错。SCAN 反向时必须由近及远。
八、真题 2015(32):SCAN 移过的磁道数
200 个磁道(外侧 0 号),请求 130、42、180、15、199,磁头在 58,从外侧向内侧移动。
先翻译方向:外侧是 0,向内侧移动 = 磁道号增大。
按 SCAN 走:
58 → 130 → 180 → 199 → (反向)→ 42 → 15 72 + 50 + 19 + 157 + 27 = 325
答案 C:325。
这道题两个坑:一是方向(把「向内侧」当成减小,就会先去 42、15,得 287,正好是选项 B);二是 199 本身是请求,所以不需要空跑到 199,直接在此回头。
九、真题 2021(26):SSTF 的移动距离
磁道 0~199,磁头在 184,请求依次为 184、187、176、182、199,用 SSTF 求移动距离。
每次挑最近的:
184(距离 0)→ 182(2)→ 187(5)→ 176(11)→ 199(23) 合计 = 0 + 2 + 5 + 11 + 23 = 41
答案 C:41。
注意第一步:184 本身就是请求,距离 0,必须先服务它。有人跳过它直接去 182,就会多算一次往返。SSTF 的第一步永远先看「当前磁道有没有请求」。
十、真题 2024(32):CSCAN 的移动距离
400 个磁道(0~399),CSCAN 调度,完成 200 号磁道请求后磁头向磁道号减小方向移动。还有 7 个请求:300、120、110、0、160、210、399。
按 CSCAN 单向扫:
-
向减小方向,把小于 200 的请求按降序服务:160 → 120 → 110 → 0;
-
到 0 后跳到另一端最高请求 399;
-
再向减小方向:300 → 210。
200→160 = 40 160→120 = 40 120→110 = 10 110→0 = 110 (前四段合计 200,正好从 200 走到 0) 0→399 = 399 (跳回) 399→300 = 99 300→210 = 90 合计 = 200 + 399 + 99 + 90 = 788
答案 C:788。
这道题验证了 CSCAN 的口径:跳回要计满整个跨度(0 → 399 = 399 个磁道),不能只算到「下一个请求」。也顺便说明为什么 CSCAN 平均性能不一定比 SCAN 好——跳回那一下是纯浪费,换来的是两端等待时间均匀。
十一、磁臂黏着与饥饿
2018 年第 30 题:系统总访问某个磁道而不理其他请求,叫磁臂黏着。问哪种算法不会导致——答案 A:FCFS。
原理:SSTF 每次选最近,如果新请求不断落在磁头附近,远处的请求就永远排不上;SCAN / CSCAN 有方向约束,扫过去一定会覆盖到,所以不会黏着;FCFS 严格按到达顺序,更不会。
这里有个容易混的点:SCAN 和 CSCAN 不会「饥饿」,但会有「等待时间不均」——SCAN 里刚被扫过的那个端点,要等磁头跑到另一端再回来,等待时间最长。CSCAN 就是为修这个而生的。
把这个「上界」量化一下就清楚了。SCAN 扫完一趟最坏要走约 2 倍的全跨度(过去再回来),所以任何请求的等待都不会超过「两趟扫描」的时间;SSTF 没有这个上界,理论上可以无限等。CSCAN 把「回来」那趟省掉(跳回不走磁道),代价是跳回时不做服务,所以最大等待变成一趟扫描 + 一次跳回,比 SCAN 更均匀。考试问「哪个算法最公平」,答案不是 FCFS 就是 CSCAN:FCFS 按到达顺序最讲道理,CSCAN 在性能与公平之间最平衡。
十二、格式化:低级与高级
磁盘的「格式化」有两层,别混:
| 类型 | 又叫 | 谁做 | 做什么 |
|---|---|---|---|
| 低级格式化(物理格式化) | 物理格式化 | 厂家 | 划分扇区、写校验码、建立物理地址 |
| 高级格式化(逻辑格式化) | 逻辑格式化 | 装系统时 | 建立文件系统:分区、根目录、空闲块管理结构 |
2017 年第 29 题问逻辑格式化做的工作,答案 B:仅 Ⅱ、Ⅳ——建立文件系统的根目录、对保存空闲磁盘块信息的数据结构进行初始化。
Ⅰ「对磁盘进行分区」是分区工具做的事,Ⅲ「确定扇区校验码位数」是出厂物理格式化的事。这两项是标准干扰项。
十三、分区、引导与操作系统加载
开机到系统跑起来,大致这条链:
加电 → BIOS/UEFI 自检 → 读主引导记录 MBR → 找到活动分区 → 加载引导程序 → 加载操作系统内核
2013 年第 29 题问「计算机开机后操作系统最终被加载到」——答案:主存(选 D)。这个考点看着简单,错的人不少:引导程序、内核镜像都存在磁盘上,但最终执行必须在主存,因为 CPU 只能直接访问内存。
补几个常一起考的名词:MBR(主引导记录)占磁盘第一个扇区共 512B,里面装着引导代码和分区表(分区表 64B,最多 4 个主分区),末尾两个字节是 55AA 作为合法标志;活动分区是分区表里被标记为可引导的那一个;引导程序(如 GRUB)的任务是把内核镜像从分区读进内存并跳转执行。所以整条链是「固件 → MBR → 引导程序 → 内核 → 初始化进程」,每一棒都在磁盘上,但交接的那一刻必须已经进内存。
2014 年第 26 题补了另一半:一个进程的读磁盘操作完成后,操作系统必做的是「唤醒该进程」(选 A)。I/O 完成 → 中断 → 驱动 → 唤醒等待队列里的进程,这条链在 OS09 讲过,这里落在「谁被唤醒」上。
十四、簇与磁盘空间管理
文件系统不用「扇区」当分配单位,而是把若干连续扇区打包成簇(块)。
2017 年第 26 题:簇 1KB、扇区 512B,文件大小 1026B,问分配的空间。1026B 要占 2 个簇(1KB 装不下),2 × 1KB = 2048B,答案 D。
这题考的是内部碎片:最后一个簇只用了一点点,剩下的 1022B 全浪费。所以簇不能太大(浪费空间),也不能太小(元数据太多、块数暴涨),4KB 是常见折中。
空闲块管理的方法(位图、空闲链表、成组链接、FAT)在 OS08 已展开,这里只强调一句:位图用 1 位表示一个簇,所以位图大小 = 簇数 ÷ 8 字节。2014(27)、2015(31) 两道计算题都是这个公式的变体。
十五、提高磁盘 I/O 性能的手段
2012 年第 32 题问「不能改善磁盘 I/O 性能的是」——答案 B:在一个磁盘上设置多个分区。
分区只是逻辑切分,磁头还是一个、寻道还是那么多,零收益。真正的三板斧:
| 层次 | 手段 | 作用 |
|---|---|---|
| 调度层 | 重排 I/O 请求(SCAN/CSCAN) | 减少寻道 |
| 缓冲层 | 磁盘高速缓存、预读、延迟写 | 减少 I/O 次数 |
| 布局层 | 连续分配、同一柱面集中、扇区交叉编号 | 减少寻道与旋转延迟 |
2018 年第 31 题把这四项摆在一起:提前读、分配连续簇、延迟写、磁盘高速缓存——四项全能提高文件访问速度(选 D)。
再往上还有一层「硬件并行」的手段,考纲只要求认得名字:
| 手段 | 做法 | 提升的是 |
|---|---|---|
| RAID 0 | 数据条带化分散到多盘,无冗余 | 读写带宽(容量全用,但不安全) |
| RAID 1 | 两盘互为镜像 | 可靠性 + 读带宽(写要写两份) |
| RAID 5 | 条带 + 分布式奇偶校验 | 容量、速度、可靠性折中(允许坏一盘) |
记住一句话就够判题:RAID 0 快但不安全,RAID 1 安全但费盘,RAID 5 是折中;三者都是靠「多盘并行」提升吞吐,而不是降低单盘延迟。
十六、SSD 与 HDD:哪些概念不通用
2025 年第 32 题问:文件系统能为温彻斯特硬盘(HDD)和 SSD 都提供的功能是什么?答案 B:确定盘块大小。
逐项拆:
-
划分扇区(A):出厂物理格式化,厂家干,文件系统不干;
-
确定盘块大小(B):逻辑格式化的核心动作,两种盘都需要,✅;
-
降低寻道时间(C):寻道是 HDD 的机械概念,SSD 根本没有;
-
实现均衡磨损(D):SSD 控制器特有的功能(把写操作摊到不同闪存块,延长寿命)。
SSD 的特点补三句:没有机械部件(寻道、旋转延迟都不存在)、读写单位是页、擦除单位是块(写前要先擦,所以随机写比随机读慢)、有擦写寿命(才需要磨损均衡)。
再往深一层,SSD 内部靠 FTL(闪存转换层)维护「逻辑块号 → 物理页」的映射,操作系统看到的「盘块」其实是映射出来的虚拟地址。这带来一个 HDD 没有的现象——写放大:改 4KB 的数据,可能要先把整个擦除块(几百 KB)读出来、改完、再写回去,实际写入量远大于请求量。TRIM 指令的作用就是告诉 SSD「这些块文件系统不要了」,让它提前回收,减少擦除时的搬迁。这些细节不考计算,但「SSD 没有寻道、写前要擦、有寿命」这三句足以应付所有判断题。这也解释了为什么磁盘调度算法对 SSD 意义不大——没有寻道可优化。
十七、易错点红黑榜与考频
| ❌ 容易错 | ✅ 正确 |
|---|---|
| 扇区号从 0 开始 | 扇区从 1 开始,柱面/磁头从 0 |
| 平均旋转延迟按一圈算 | 按半圈:½ × 60/r |
| SCAN 反向时按升序服务 | 反向必须降序(由近及远) |
| 「向内侧移动」当成磁道号减小 | 外侧是 0,向内侧 = 增大 |
| CSCAN 跳回只算到下一个请求 | 跳到另一端,跨度要计满 |
| SSTF 会饥饿 = SCAN 也会 | SCAN/CSCAN 不会饥饿,只是等待不均 |
| 逻辑格式化包括分区 | 分区不是格式化,校验码位数是物理格式化 |
| 磁盘调度也能优化旋转延迟 | 调度只优化寻道 |
| 考点 | 年份 | 频次 |
|---|---|---|
| 磁盘调度计算 | 2009(29)、2015(32)、2018(30)、2021(26)、2024(32) | 5 |
| 访问时间三段式 | 与调度题混合出现 | 高频 |
| 格式化 / 分区 / 引导 | 2013(29)、2017(29) | 2 |
| 簇与空间分配 | 2014(27)、2015(31)、2017(26) | 3 |
| 性能优化 | 2012(32)、2018(31)、2025(32) | 3 |
十八、速查表(文末收藏版)
结构:盘面 → 磁道(同心圆)→ 扇区(从 1 编);同半径磁道 = 柱面。地址 = CHS,由驱动算。
容量 = 盘面数 × 每面磁道数 × 每道扇区数 × 扇区大小。
访问时间 = 寻道 Ts + 旋转 Tr + 传输 Tt; Tr = ½ × 60/r;Tt = 数据量 ÷ (每道字节数 × r/60)。
四算法(53 起,请求 98/183/37/122/14/124/65/67):FCFS 640、SSTF 236、SCAN 299、CSCAN 322。
真题答案:2009(29) A|2015(32) 325|2021(26) 41|2024(32) 788|2018(30) FCFS|2017(29) Ⅱ、Ⅳ|2013(29) 主存|2017(26) 2048B|2025(32) 确定盘块大小。
一句话判方向:SCAN 扫到本方向最后一个请求就回头;CSCAN 跳到另一端继续同向;两者都不会饥饿,SSTF 会。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
—— 访问时间三段式与机械/电子时间占比
—— 四种调度算法的磁头轨迹对比
所有评论(0)