操作系统———磁盘调度算法模拟

  • 实验目的

 磁盘是可供多个进程共享的设备,当有多个进程都要求访问磁盘是,应采用一种最佳调度算法,以使各进程对磁盘的平均访问时间最小。目前最成用的磁盘调度算法有先来先服务(FCFS),最短寻道时间优先(SSTF),以及扫描算法(SCAN)。通过本实验可以加深理解有关磁盘调度的目标,并体会和了解最短寻道时间优先算法和扫描算法的具体实施办法。

  • 实验内容

1 100#磁道开始,被访问的磁道号分别为:555839189016015038184

2 要求用最短寻道时间优先算法的和扫描算法实现磁盘调度。

3 记录下每访问一个磁道磁头移动的磁道数,并计算平均寻道长度(平均移动磁道数)。,,

  • 实验要求

分别用两种算法实现磁盘调度。在实验结果分析中,将比较结果以列表的形式表现出来。用数组(或链表)TR[ ]存储待访问磁道号,将每次磁头移动磁道数用数组AR[ ] 存储。输出结果应如下例:(注意空格)

150

50

160

10

184

24

18,,

166

38

20

39

1

55

16

58

3

90

32

平均寻道长度:35.8

  • 编程工具:

C++语言平台(DevC++开发工具)

五、

(1)问题概述

  1. 磁盘调度算法的目的是优化磁盘I/O操作,减少磁头移动距离,从而提高磁盘I/O效率。
  2. 常见的磁盘调度算法包括:先来先服务(FCFS)算法、最短寻道时间优先(SSTF)算法、轮转优先(SCAN)算法、最少最近使用(LRU)算法等。
  3. FCFS算法按请求到达顺序依次处理请求,简单但效率低下。SSTF算法选择离当前磁头位置最近的请求处理,可以减少磁头移动但难以实现。
  4. SCAN算法将磁盘划分为多个区,依次扫描每个区处理请求,减少磁头移动但响应时间长。LRU算法优先处理最近最久未使用的磁盘块,需要记录使用信息增加开销。

(2)整体功能及设计

通过构建最短寻道时间优先算法函数、构建扫描算法函数,然后将创作主函数循环调用,并能够输出调度过程以及平均寻道长度。

(3)编程实现(附代码和截图)

#include<stdio.h> 
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
//55 58 39 18 90 160 150 38 184
void SSTF(int a[], int n) {//最短寻道时间优先调度
    int site = 1;//确定开始磁道中间位置
    int m, Left, Right;
    int i, j, sum = 0;
    double Average=0;
    int Temp; 
    sort(a, a + n);//对磁道号进行从小到大排列
    printf("排序后磁道数组如下:\n");
    for (i = 0; i < n; i++) //输出排序后的磁道号数组
        printf("%d ", a[i]);
    printf("\n请输入开始的磁道号: ");
    scanf("%d", &m);
    printf("\nSSTF(最短寻道优先)调度过程如下: \n");
    printf("\n被访问的下一个磁道号             移动距离(磁道数)\n"); 
    int mark = m;//用来计算差值或移动距离
    if (a[n - 1] <= m)//整个数组里的数都小于开始磁道号的情况
    {
        for (i = n - 1; i >= 0; i--) { //将数组磁道号就逆序输出
            printf("%10d ---------------------- %-3d\n", a[i], mark - a[i]);
            mark = a[i];
        }
        sum = m - a[0];
    }
    else if (a[0] >= m)//整个数组里的数都大于开始磁道号的情况
    {
        for (i = 0; i < n; i++) { //将磁道号从小到大顺序输出
            printf("%10d ---------------------- %-3d\n", a[i], a[i] - mark);
            mark = a[i];
        }
        sum = a[n - 1] - m;
    }
    else
    {
        while (a[site] < m)//找位置
        {
            site++;
        }
        Left = site - 1;
        Right = site;
        //确定开始磁道在已排的序列中的位置
        while ((Left >= 0) && (Right < n))
        {
            if ((m - a[Left]) <= (a[Right] - m))//找最短距离是在左侧还是右侧
            {
                printf("%10d ---------------------- %-3d\n", a[Left], mark - a[Left]);
                mark = a[Left];
                sum += m - a[Left];
                m = a[Left];
                Left = Left - 1;
            }
            else//在右侧
            {
                printf("%10d ---------------------- %-3d\n", a[Right], a[Right] - mark);
                mark = a[Right];
                sum += a[Right] - m;
                m = a[Right];
                Right = Right + 1;
            }
        }
        if (Left = -1)
        {
            for (j = Right; j < n; j++)//顺序输出 
            {
                printf("%10d ---------------------- %-3d\n", a[j], a[j] - mark);
                mark = a[j];
            }
            sum += a[n - 1] - a[0];
        }
        else
        {
            for (j = Left; j >= 0; j--)//逆序输出 
            {
                printf("%10d ---------------------- %-3d\n", a[j], mark - a[j]);
                mark = a[j];
            }
            sum += a[n - 1] - a[0];
        }
    }
    printf("\n");
    Average = (double)sum / n;
    printf(" 可见平均寻道的长度为: %.2f \n", Average);
}
 
void SCAN(int a[], int n) {///扫描算法或电梯调度算法
    int i, j, sum = 0;
    double Average;
    for (i = 0; i < n; i++)
    {
        sort(a, a + n);//升序排序
    }
    printf("排序后的磁道数组如下:\n");
    for (i = 0; i < n; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n请输入开始的磁道号: ");
    int m;
    scanf("%d", &m);
    printf("\nSCAN(扫描或电梯)调度过程如下:\n");
    printf("\n被访问的下一个磁道号             移动距离(磁道数)\n"); 
    int pointer;
    int mark = m;
    for (i = 0; i < n; i++)
    {
        if (a[i] >= m)//找到比开始磁道号大的数 
        {
            pointer = i;
            sum += abs(a[i] - m);
            break;
        }
    }
    for (i = pointer; i < n; i++)
    {
        if (i != pointer)//顺着磁头方向顺序输出 
            sum += abs(a[i] - a[i - 1]);
        printf("%10d ---------------------- %-3d\n", a[i], a[i] - mark);
        mark = a[i];
    }
    if (pointer >= 1)
        sum += abs(a[n - 1] - a[pointer - 1]);
    for (i = pointer - 1; i >= 0; i--)//逆着磁头方向顺序输出 
    {
        if (i)
            sum += abs(a[i] - a[i - 1]);
        printf("%10d ---------------------- %-3d\n", a[i], mark - a[i]);
        mark = a[i];
    }
    Average = (double)sum / n;
    printf("\n 平均寻道的长度为:%.2f\n", Average);
}
int main() {
    int track[100];//定义磁道号数组
    int select;
    int i = 0;
    int n;
    printf("请先输入磁道数量: \n");
    scanf("%d", &n);
    printf("请先输入磁道序列: \n");
    for (i = 0; i < n; i++)
    {
        scanf("%d", &track[i]);
    }
 
 
    printf("\n");
    while (1)
    {
        printf("1.最短寻道时间优先算法(SSTF) \n");
        printf("2.扫描算法(SCAN)\n");
        printf("3.退出\n");
        printf("\n");
        printf("请选择要使用的调度算法: ");
        scanf("%d", &select);
 
        switch (select)//算法选择
        {
        case 1:
            SSTF(track, n);//最短服务时间优先算法
            printf("\n");
            break;
        case 2:
            SCAN(track, n);//扫描算法
            printf("\n");
            break;
        case 3:
            exit(0);
        }
    }
    return 0;
}

(4)使用说明

输入磁道数量、输入磁道序列、然后回车根据菜单选择相应的调度算法。

(5)结果分析

1. 最短寻道时间优先算法(Shortest Seek Time First, SSTF)

- 优点:能有效减少磁头移动距离,从而减少平均I/O等待时间。

- 缺点:可能导致 starvation,后来请求的I/O等待时间可能很长。

2. 扫描算法(SCAN)

- 优点:能较好避免 starvation 问题,后来请求不会等待过长时间。

- 缺点:磁头移动距离可能较大,平均I/O等待时间较长。

3. 对比分析:

- SSTF算法在减少磁头移动距离上优于SCAN算法,平均I/O等待时间可能较短。

- 但SSTF可能出现一个请求等待时间特别长的情况,不如SCAN在公平性上。

- SSTF更依赖请求分布,如果请求分布不均匀,性能下降明显。

- SCAN算法性能更稳定,不易受请求分布影响。但移动距离较大,平均等待时间较长。

4. 综上,在I/O等待时间优先的场景下,SSTF算法效果较好;在公平性和稳定性要求较高的场景,SCAN算法更适用。

5. 实际使用中,也可以根据负载动态调整两种算法,兼顾等待时间和公平性的优点。

所以两种算法各有优劣,需要根据实际场景具体选择或结合使用,以达到最佳磁盘调度效果。

(6)设计体会

操作系统磁盘调度算法设计和实现给我带来以下几点体会:

1. 磁盘调度算法直接影响系统I/O性能,是操作系统优化的重要一环。不同算法在不同场景下会有很大差异。

2. 算法设计需要考虑公平性、等待时间、移动距离等多方面因素,难度较大。一个好的算法需要兼顾各项指标。

3. 实际系统I/O请求模式复杂,简单的算法在实际中效果可能不如预期。需要结合负载动态调整策略。

4. 算法实现需要考虑多磁盘和多请求并发场景,数据结构和同步机制的设计很重要。

5. 不同算法在不同系统和应用场景下性能也会有差异。需要通过实验对比分析不同参数和场景下的优劣。

7. 算法是一个需要不断优化和更新的模块。需要提供良好的扩展接口支持后期升级。

8. 理解主流算法原理和思路,对设计和优化自己的算法很有帮助。

9. 磁盘调度涉及操作系统、算法和性能优化多个知识点。整个设计过程让我对系统有了更深入的认识。

总体来说,磁盘调度算法设计是一个系统性和实践性很强的学习过程,给我带来很多收获。它也反映了操作系统研发需要考虑的各个方面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/231525.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

增加网站流量的方法

如果您的网站没有获得足够的流量&#xff0c;您可能会错过在线发展业务的重要机会。搜索引擎优化&#xff08;SEO&#xff09;可以帮助提高您网站的知名度&#xff0c;从而吸引更多客户。 SEO的重点是识别高价值的关键词&#xff0c;并将它们整合到网站的内容中&#xff0c;使…

【设计模式-3.2】结构型——适配器模式

说明&#xff1a;本文介绍设计模式中结构型设计模式中的&#xff0c;适配器模式&#xff1b; 插头转换器 适配器模式属于结构型设计模式&#xff0c;设计思想体现在结构上的。以插头转换器为例&#xff0c;当你需要给手机充电&#xff0c;但是眼前只有一个三孔插座&#xff0…

MES管理系统在非标制造企业中的应用

在当今制造业中&#xff0c;非标制造企业逐渐成为一种重要的存在。与传统的批量生产制造企业不同&#xff0c;非标制造企业主要特点是能够根据客户需求进行定制化生产。这种定制化的生产模式对企业的管理提出了更高的要求&#xff0c;同时也带来了更多的挑战。在非标制造企业中…

Emacs之Plantuml用于复杂UML类图(Markdown用于简单类图)(一百三十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

MQTT主题、通配符和最佳实践

MQTT主题在MQTT生态系统非常重要&#xff0c;因为代理&#xff08;broker&#xff09;依赖主题确定哪个客户端接收指定的主题。本文我们将聚集MQTT主题、MQTT通配符&#xff0c;详细讨论使用它们的最佳实践&#xff0c;也会探究SYS主题&#xff0c;提供给代理&#xff08;broke…

超越极限!如何进行高效分布式性能测试,让Jmeter揭示并发下系统的真正实力

一、为什么要进行分布式性能测试 当进行高并发性能测试的时候&#xff0c;受限于Jmeter工具本身和电脑硬件的原因&#xff0c;无法满足我们对大并发性能测试的要求。 基于这种场景下&#xff0c;我们就需要采用分布式的方式来实现我们高并发的性能测试要求。 二、分布式性能测…

深度学习记录--激活函数

激活函数的种类 对于激活函数的选择&#xff0c;通常有以下几种 sigmoid&#xff0c;tanh&#xff0c;ReLU&#xff0c;leaky ReLU 激活函数的选择 之前logistic回归一直使用的激活函数都是sigmoid函数&#xff0c;但一般来说&#xff0c;tanh函数是比sigmoid函数更加好的选…

【小白专用】在 vs 中使用 nuget 安装NPOI

C#操作Excel有多种方法&#xff0c;如通过数据库的方式来读写Excel的OleDb方式&#xff0c;但是OleDb方式需要安装微软office&#xff0c;还可以通过COM组件方式操作Excel&#xff0c;也需要安装微软Excel。如果不想安装微软办公套餐可以使用ClosedXML、EPPlus、NPOI。本文主要…

理解IoC容器初始化

问题&#xff1a;当自己面试或者背诵八股文时&#xff0c;会背到各种各样的spring底层的东西&#xff0c;自己越看越迷糊。 OS&#xff1a;不知道兄弟们是不是也会这样&#xff1f;如果大家没有说明我太菜了。 原因&#xff1a;就是自己学的框架越来越多&#xff0c;很多框架…

线性回归实战

3.1 使用正规方程进行求解 3.1.1 简单线性回归 公式 &#xff1a; y w x b y wx b ywxb 一元一次方程&#xff0c;在机器学习中一元表示一个特征&#xff0c;b表示截距&#xff0c;y表示目标值。 使用代码进行实现&#xff1a; 导入包 import numpy as np import matp…

bc-linux-欧拉重制root密码

最近需要重新安装虚拟机的系统 安装之后发现对方提供的root密码不对&#xff0c;无法进入系统。 上网搜了下发现可以进入单用户模式进行密码修改从而重置root用户密码。 在这个界面下按e键 找到图中部分&#xff0c;把标红的部分删除掉&#xff0c;然后写上rw init/bin/…

JAVEE初阶 多线程基础(七)

懒汉模式 指令重排序问题 一. 懒汉模式的意义和代码实现二. 饿汉模式和懒汉模式的线程安全三. 懒汉模式的线程安全问题解决3.1 加锁阶段3.2 嵌套if阶段3.3 指令重排序问题3.4 解决线程安全问题阶段 一. 懒汉模式的意义和代码实现 在上一章节中,我们先学习了单例模式中的饿汉模式…

【好书推荐】《深入Activiti流程引擎:核心原理与高阶实战》

学习工作流&#xff0c;推荐贺老师的书《深入Activiti流程引擎&#xff1a;核心原理与高阶实战》&#xff0c;对系统学习和深入掌握Activiti/Flowable流程引擎的用法非常有帮助。 图书链接

我的NPI项目之Android电源系列 -- 关于剩余充满时间的问题(一)

我的新项目是基于高通最新的5G平台&#xff0c;但是由于还没有拿到EVT。所以&#xff0c;就在目旧的平台和OS上进行学习。遇到第一个问题就是插上type-c之后&#xff0c;充满剩余时间异常的问题。 问题描述&#xff0c;在充电过程中&#xff0c;显示充满时间为“0 min left unt…

基于EIoT能源物联网的智能照明系统应用改造-安科瑞 蒋静

【摘要】&#xff1a;随着物联网技术的发展&#xff0c;许多场所针对照明合理应用物联网照明系统&#xff0c;照明作为工厂的重要能耗之一&#xff0c;工厂的照明智能化控制&#xff0c;如何优化控制、提高能源的利用率&#xff0c;达到节约能源的目的。将互联网的技术应用到工…

MCS-51系列与AT89C5x系列单片机的介绍与AT系列的命名规则

MCS-51系列与AT89C5x系列单片机 主要涉及MCS-51系列与AT89C5x系列单片机的介绍与AT系列单片机的命名规则 文章目录 MCS-51系列与AT89C5x系列单片机一、 MCS-51系列单片机二、AT89C5x系列单片机2.1 AT89C5x/AT89S5x系列单片机的特点2.2 AT89系列单片机的型号说明2.2.1 前缀2.2.2…

PyTorch: 基于VGG16处理MNIST数据集的图像分类任务

引言 在本博客中&#xff0c;小编将向大家介绍如何使用VGG16处理MNIST数据集的图像分类任务。MNIST数据集是一个常用的手写数字分类数据集&#xff0c;包含60,000个训练样本和10,000个测试样本。我们将使用Python编程语言和PyTorch深度学习框架来实现这个任务。 在Conda虚拟环…

【剑指offer|图解|数组】寻找文件副本 + 螺旋遍历二维数组

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、剑指offer每日一练 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️寻找文件副本(题目难度&#xff1a;简单)1.1 题目1.2 示例1.3 限制1.4 解题思路一c代…

【链表OJ—分割链表】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 1、分割链表题目&#xff1a; 方法讲解&#xff1a; 图文解析&#xff1a; 代码实现&#xff1a; 总结 前言 世上有两种耀眼的光芒&#xff0c;一种是正在升起的太…

坚鹏:中国工商银行浙江大学金融业务转型与场景营销策略培训

中国工商银行打造D-ICBC数字化转型战略&#xff0c;围绕“数字生态、数字资产、数字技术、数字基建、数字基因”五维布局&#xff0c;深入推进数字化转型&#xff0c;加快形成体系化、生态化实施路径&#xff0c;促进科技与业务加速融合&#xff0c;以“数字工行”建设推动“GB…