当前位置: 首页 > news >正文

八:操作系统设备管理之磁盘调度算法

操作系统如何让硬盘动起来?—— 深入探讨磁盘调度算法

在现代计算机系统中,数据存储是核心功能之一。尽管固态硬盘(SSD)越来越普及,但传统的机械硬盘(HDD)因其大容量和较低的成本,仍然广泛应用于服务器、数据中心以及许多个人电脑中。正如我们在关于磁盘结构的讨论中所知,机械硬盘的数据访问涉及到机械部件的移动——特别是读写磁头臂的寻道(Seek)操作,这比电子操作(如内存访问)慢得多。

操作系统负责管理对硬盘的访问请求。当多个进程同时需要从硬盘读取或写入数据时,就会产生一系列的磁盘I/O请求队列。每个请求都指向硬盘上的特定位置,通常由柱面(或逻辑块地址LBA)标识。如果不加调度地响应这些请求,磁头可能会在盘片上频繁地大幅度来回移动,导致大量的寻道时间消耗,极大地降低硬盘的吞吐量和系统的整体性能。

为了解决这个问题,操作系统引入了磁盘调度算法 (Disk Scheduling Algorithms)。这些算法的目标是优化服务请求的顺序,以最小化总的磁头移动时间,从而提高硬盘访问效率。

想象一个场景:硬盘磁头当前位于柱面号50。现在有一个请求队列,包含对以下柱面的访问请求:98, 183, 37, 122, 14, 124, 65, 67。我们将使用这个队列作为例子,看看不同的调度算法如何处理它,以及它们各自的总磁头移动距离是多少。假设柱面号范围是0到199。

我们将逐一介绍几种经典的磁盘调度算法。

1. 先来先服务 (FCFS - First-Come, First-Served)

基本原理: 最简单的调度算法。按照请求到达的顺序依次服务。

工作机制: 不考虑请求的物理位置,只按照请求进入队列的先后顺序进行处理。

示例:
当前磁头位置:50
请求队列(到达顺序):98, 183, 37, 122, 14, 124, 65, 67

服务顺序:

  1. 从 50 到 98:移动距离 |98 - 50| = 48
  2. 从 98 到 183:移动距离 |183 - 98| = 85
  3. 从 183 到 37:移动距离 |37 - 183| = 146
  4. 从 37 到 122:移动距离 |122 - 37| = 85
  5. 从 122 到 14:移动距离 |14 - 122| = 108
  6. 从 14 到 124:移动距离 |124 - 14| = 110
  7. 从 124 到 65:移动距离 |65 - 124| = 59
  8. 从 65 到 67:移动距离 |67 - 65| = 2

总磁头移动距离 = 48 + 85 + 146 + 85 + 108 + 110 + 59 + 2 = 643

优点: 公平,每个请求都能按其到达顺序得到服务,不会饥饿。实现简单。
缺点: 不考虑磁盘的物理结构,可能导致磁头在磁盘上来回频繁移动,寻道效率低,特别是在请求分布比较分散的情况下。总寻道时间通常不是最优的。

2. 最短寻道时间优先 (SSTF - Shortest-Seek-Time First)

基本原理: 优先服务与当前磁头位置最近的请求。

工作机制: 从待服务的请求队列中选择距离当前磁头位置最近的那个请求进行服务。

示例:
当前磁头位置:50
请求队列:98, 183, 37, 122, 14, 124, 65, 67

服务顺序(选择距离最近的):

  1. 从 50 开始。请求队列距离:|98-50|=48, |183-50|=133, |37-50|=13, |122-50|=72, |14-50|=36, |124-50|=74, |65-50|=15, |67-50|=17。最近的是 37 (13)。
    从 50 到 37:移动距离 |37 - 50| = 13。 服务完 37。剩余队列:98, 183, 122, 14, 124, 65, 67。
  2. 当前 37。剩余队列距离:|98-37|=61, |183-37|=146, |122-37|=85, |14-37|=23, |124-37|=87, |65-37|=28, |67-37|=30。最近的是 14 (23)。
    从 37 到 14:移动距离 |14 - 37| = 23。 服务完 14。剩余队列:98, 183, 122, 124, 65, 67。
  3. 当前 14。剩余队列距离:|98-14|=84, |183-14|=169, |122-14|=108, |124-14|=110, |65-14|=51, |67-14|=53。最近的是 65 (51)。
    从 14 到 65:移动距离 |65 - 14| = 51。 服务完 65。剩余队列:98, 183, 122, 124, 67。
  4. 当前 65。剩余队列距离:|98-65|=33, |183-65|=118, |122-65|=57, |124-65|=59, |67-65|=2。最近的是 67 (2)。
    从 65 到 67:移动距离 |67 - 65| = 2。 服务完 67。剩余队列:98, 183, 122, 124。
  5. 当前 67。剩余队列距离:|98-67|=31, |183-67|=116, |122-67|=55, |124-67|=57。最近的是 98 (31)。
    从 67 到 98:移动距离 |98 - 67| = 31。 服务完 98。剩余队列:183, 122, 124。
  6. 当前 98。剩余队列距离:|183-98|=85, |122-98|=24, |124-98|=26。最近的是 122 (24)。
    从 98 到 122:移动距离 |122 - 98| = 24。 服务完 122。剩余队列:183, 124。
  7. 当前 122。剩余队列距离:|183-122|=61, |124-122|=2。最近的是 124 (2)。
    从 122 到 124:移动距离 |124 - 122| = 2。 服务完 124。剩余队列:183。
  8. 当前 124。剩余队列距离:|183-124|=59。最近的是 183 (59)。
    从 124 到 183:移动距离 |183 - 124| = 59。 服务完 183。剩余队列:空。

总磁头移动距离 = 13 + 23 + 51 + 2 + 31 + 24 + 2 + 59 = 205

优点: 相较于FCFS,SSTF通常能够显著减少总磁头移动距离,提高吞吐量。
缺点: 不保证公平性,远离当前磁头位置的请求可能会因为总有新的更近的请求到达而“饥饿”。

3. 扫描 (SCAN / 电梯算法)

基本原理: 磁头像电梯一样,在一个方向上移动,沿途服务遇到的所有请求,直到到达该方向的尽头(或最远请求)。然后反向移动,再次服务沿途遇到的请求。

工作机制: 需要确定磁头移动的初始方向(例如,向高柱面号移动)。磁头沿该方向扫描,服务所有遇到的请求。到达尽头后反向扫描,服务另一方向的请求。

示例:
当前磁头位置:50
请求队列:98, 183, 37, 122, 14, 124, 65, 67
假设初始方向是向高柱面号移动。柱面范围0-199。

服务顺序:

  1. 从 50 开始,向高移动。服务沿途遇到的请求(按柱面号排序):65, 67, 98, 122, 124, 183。
    从 50 到 65:移动距离 |65 - 50| = 15
    从 65 到 67:移动距离 |67 - 65| = 2
    从 67 到 98:移动距离 |98 - 67| = 31
    从 98 到 122:移动距离 |122 - 98| = 24
    从 122 到 124:移动距离 |124 - 122| = 2
    从 124 到 183:移动距离 |183 - 124| = 59
  2. 磁头到达最高请求柱面 183。现在反向移动,服务剩余请求:37, 14。
    从 183 到 37:移动距离 |37 - 183| = 146
    从 37 到 14:移动距离 |14 - 37| = 23

总磁头移动距离 = 15 + 2 + 31 + 24 + 2 + 59 + 146 + 23 = 302
(注意:如果 SCAN 规定必须扫描到硬盘的物理边界,例如柱面199,那么第一步会从183移动到199,再从199反向。移动距离会是 15+2+31+24+2+59 + |199-183| + |37-199| + |14-37| = 15+2+31+24+2+59 + 16 + 162 + 23 = 334。实际实现可能略有不同,此处按扫描到最远请求柱面计算。)

优点: 避免饥饿,对所有请求提供相对公平的服务。对请求分布均匀的情况表现良好。
缺点: 靠近当前磁头位置且位于扫描方向后方的请求需要等待磁头扫描到一端再返回,等待时间可能较长。

4. 循环扫描 (C-SCAN - Circular SCAN)

基本原理: 类似于SCAN,但只在一个方向上服务请求。当磁头到达一端时,它会立即“跳跃”到另一端,而不在返回途中服务任何请求,然后再次开始单向扫描。

工作机制: 磁头只在一个指定方向(如向高柱面号)服务请求。到达该方向的尽头后,迅速回到另一端的起始位置(通常是柱面0),然后再次开始向指定方向扫描。

示例:
当前磁头位置:50
请求队列:98, 183, 37, 122, 14, 124, 65, 67
假设服务方向是向高柱面号移动。柱面范围0-199。

服务顺序:

  1. 从 50 开始,向高移动,服务沿途遇到的请求:65, 67, 98, 122, 124, 183。
    从 50 到 65:移动距离 |65 - 50| = 15
    从 65 到 67:移动距离 |67 - 65| = 2
    从 67 到 98:移动距离 |98 - 67| = 31
    从 98 到 122:移动距离 |122 - 98| = 24
    从 122 到 124:移动距离 |124 - 122| = 2
    从 124 到 183:移动距离 |183 - 124| = 59
  2. 磁头到达最高请求柱面 183。现在“跳跃”回最低柱面 0。
    从 183 到 0:移动距离 |0 - 183| = 183 (这个跳跃过程中不服务请求)
  3. 从柱面 0 开始,再次向高移动,服务剩余请求(这些请求原本在初始位置50的左侧):14, 37。
    从 0 到 14:移动距离 |14 - 0| = 14
    从 14 到 37:移动距离 |37 - 14| = 23

总磁头移动距离 = 15 + 2 + 31 + 24 + 2 + 59 + 183 (跳跃) + 14 + 23 = 353
(注意:C-SCAN通常会扫到物理边界,比如从183扫到199,再跳回0。那么跳跃距离就是 |0-199| = 199。总距离会是 15+2+31+24+2+59 + |199-183| + |0-199| + |14-0| + |37-14| = 15+2+31+24+2+59 + 16 + 199 + 14 + 23 = 385。此处按扫到物理边界计算。)

优点: 提供比SCAN更均匀的等待时间,避免饥饿。因为只单向服务,同一方向上的请求等待时间相对稳定。
缺点: 可能导致比SCAN更高的总寻道时间(由于跳跃开销)。

5. LOOK 和 C-LOOK

基本原理: LOOK和C-LOOK是SCAN和C-SCAN的改进版本。它们不像原始算法那样必须扫描到磁盘的物理尽头,而是只扫描到当前队列中那个方向上的最远请求。

LOOK (SCAN变种):

  • 工作机制: 磁头在一个方向上移动,服务沿途遇到的请求,直到到达该方向上的最远请求,然后反向移动,服务另一方向的请求。

  • 示例:
    当前磁头位置:50
    请求队列:98, 183, 37, 122, 14, 124, 65, 67
    假设初始方向是向高柱面号移动。最高请求是 183,最低请求是 14。
    服务顺序:

    1. 从 50 向高服务到最远请求 183:65, 67, 98, 122, 124, 183。
      移动距离:(65-50) + (67-65) + (98-67) + (122-98) + (124-122) + (183-124) = 15 + 2 + 31 + 24 + 2 + 59 = 133
    2. 从 183 反向服务到最低请求 14:37, 14。
      移动距离:(183-37) + (37-14) = 146 + 23 = 169

    总磁头移动距离 = 133 + 169 = 302
    (注意:在这个特定的请求队列中,LOOK (302) 与 SCAN (302,如果SCAN只扫到最远请求) 的总距离恰好相同,因为最远请求183与柱面尽头199很近。但如果最远请求是150,SCAN需要扫到199再回来,而LOOK只需要扫到150。)

C-LOOK (C-SCAN变种):

  • 工作机制: 磁头在一个方向上移动,服务沿途遇到的请求,直到到达该方向上的最远请求。然后跳跃回另一个方向上的最低请求,并从那里开始再次向原方向扫描(服务剩余请求)。

  • 示例:
    当前磁头位置:50
    请求队列:98, 183, 37, 122, 14, 124, 65, 67
    假设服务方向是向高柱面号移动。最高请求是 183,最低请求是 14。
    服务顺序:

    1. 从 50 向高服务到最远请求 183:65, 67, 98, 122, 124, 183。
      移动距离:(65-50) + (67-65) + (98-67) + (122-98) + (124-122) + (183-124) = 15 + 2 + 31 + 24 + 2 + 59 = 133
    2. 从 183 跳跃回最低请求 14。
      移动距离:|14 - 183| = 169 (跳跃,不服务)
    3. 从 14 继续向高扫描,服务剩余请求:37。
      移动距离:(37-14) = 23

    总磁头移动距离 = 133 + 169 (跳跃) + 23 = 325
    (注意:在这个例子中,C-LOOK (325) 的总距离小于 C-SCAN (385),因为C-LOOK避免了扫描到柱面0和199的额外移动。)

优点: LOOK和C-LOOK通过避免扫描到磁盘物理边界的空闲区域,通常比原始的SCAN和C-SCAN具有更少的总磁头移动。它们继承了SCAN/C-SCAN的公平性和避免饥饿的特点。C-LOOK依然提供更均匀的等待时间。
缺点: 比SSTF的总寻道时间可能略高,但公平性更好。

算法比较与选择

回顾我们示例中的总移动距离:

  • FCFS: 643
  • SSTF: 205
  • SCAN (扫到最远请求): 302
  • C-SCAN (扫到物理边界): 385 (或者扫到最远请求再跳跃到最低请求,距离325 - 接近C-LOOK)
  • LOOK: 302
  • C-LOOK: 325

从总移动距离来看,SSTF在这个特定例子中表现最好。然而,SSTF牺牲了公平性。SCAN、C-SCAN、LOOK、C-LOOK在总移动距离上通常介于FCFS和SSTF之间,但提供了更好的公平性,避免了饥饿。

  • FCFS 适用于负载很轻的环境,或者对公平性要求极高且对性能不敏感的场景。
  • SSTF 倾向于最大化吞吐量(单位时间内完成的I/O请求多),适合批处理系统,但不适合对响应时间要求严格的交互式系统,因为可能导致部分请求等待时间过长。
  • SCAN/C-SCAN 及其变种 LOOK/C-LOOK 在公平性和效率之间取得了较好的平衡。C-SCAN和C-LOOK由于单向扫描,对请求的等待时间分布更均匀,更适合多用户、交互式系统。LOOK和C-LOOK通常比原始的SCAN和C-SCAN更优,因为它们避免了不必要的边缘扫描。

现代操作系统通常会采用 SCAN 或 C-SCAN 的变种(如 LOOK 或 C-LOOK)作为默认的磁盘调度算法,因为它们在吞吐量和响应时间(公平性)之间提供了较好的折衷。实际的实现可能更复杂,会考虑请求的优先级、读写请求的区别等因素。

结论

磁盘调度算法是操作系统管理慢速I/O设备、提高系统性能的关键技术之一。通过策略性地安排待服务的磁盘请求顺序,这些算法有效地减少了耗时的磁头寻道操作,从而显著提高了硬盘的吞吐量并改善了用户体验。理解这些算法的原理和权衡,有助于我们 appreciate 操作系统在底层如何默默地优化资源,使得我们的计算更加高效。


相关文章:

  • 前端面试题之浏览器存储技术Cookie、LocalStorage、SessionStorage、indexDB
  • [蓝桥杯]后缀表达式
  • Scrum基础知识以及Scrum和传统瀑布式开发的区别
  • STL优先级队列的比较函数与大堆小堆的关系
  • I.MX6ULL裸机的EPIT实验
  • 贪心,回溯,动态规划
  • 从零发布一个 Vue 3 Button 组件到 npm(基于 Vite)
  • 更改安卓虚拟机屏幕大小
  • 计算机基础知识(第四篇)
  • 2025年上海市“星光计划”第十一届职业院校技能大赛 网络安全赛项技能操作模块样题
  • 农田水利如何「聪明」起来?Modbus转Ethernet IP破解设备互联
  • 洛谷题目:P2761 软件补丁问题 (本题简单)
  • linux下覆盖率测试总结
  • App使用webview套壳引入h5(二)—— app内访问h5,顶部被手机顶部菜单遮挡问题,保留顶部安全距离
  • 从Copilot到Agent,AI Coding是如何进化的?
  • [特殊字符] 一文了解目前主流的 Cursor AI 免费续杯工具!
  • 使用logrotate切割nginx日志
  • NX985NX988美光固态闪存NY103NY106
  • 【论文解读】MemGPT: 迈向为操作系统的LLM
  • 【如何做好应用架构?】
  • 怎么写网站建设推广/杭州seo排名优化
  • 优科技网站建设/买外链
  • 帝国网站后台管理系统/网站权重查询接口
  • 网站建设哪家好/课程培训
  • 代理网站推荐/59软文网
  • 163手机移动网站/深圳搜索排名优化