电梯调度算法

磁盘是一种高速、大容量、旋转型、可直接存取的存储设备。它作为计算机系统的辅助存储器,担负着繁重的输入输出任务、在多道程序设计系统中,往往同时会有若干个要求访问磁盘的输入输出请求等待处理,这时我们就需要采用一种合适的调度算法来使各个进程对磁盘的访问时间最少,考虑到在调度进程中,只涉及到刺头的移动,所以有以下注意点:

  1.磁盘调度的目标:就是使磁盘的平均寻道时间最少

  2.寻道时间的衡量指标:磁头移动的磁道数来衡量

  3.主要的磁盘调度算法有:

     1).FCFS算法:根据进程请求访问磁盘的先后次序来调度

     2).最短寻道时间优先SSTF算法:访问的磁道与当前所在的磁道距离最短

     3).扫描SCAN算法,即电梯调度算法:与当前磁道距离最近并且是在当前扫描方向上的

     4).循环扫描CSCAN算法:规定磁头单向扫描,然后立即返回重新开始。

本篇博文主要通过代码的方式直观介绍下上述第三种算法,即电梯调度算法。

   首先对于该算法的代码实现,先确定基本流程:算法分为接收新的I/O请求并建立请求I/O表和程序和对I/O请求表中的进程进行电梯调度算法.主要的流程如下:

 对于两种分支的选择,主要通过手动输入随机数的方式确定。

                                                          

     之后编写接受请求并建立请求I/O表的程序,I/O请求表主要通过一个TreeSet集合来实现,以下是流程图(具体代码会在最后作为整体程序的一部分出现):

                                                                                        

     下面是电梯调度算法的核心代码实现的流程图:

                   

    最后,在完成相关的数据初始化工作后就可以进行程序的运行,数据的初始化包括:

    1.初始化“请求I/O”表(初始已经有若干进程(3~8个)申请访问相应磁道) 2.设置置当前移臂方向 3.设置当前磁道号

    

    不废话了,贴上我的源代码:

[java]  view plain copy
  1. package 操作系统_磁盘电梯调度算法;  
  2.   
  3. import java.util.Comparator;  
  4. import java.util.Iterator;  
  5. import java.util.Random;  
  6. import java.util.Scanner;  
  7. import java.util.TreeSet;  
  8.   
  9. class PCB {  
  10.     public int id;  
  11.     public int CiDaoNum;  
  12.     public boolean isVisited;  
  13.   
  14.     @Override  
  15.     public String toString() {  
  16.         return "进程号:" + this.id + ",其访问的磁道号:" + this.CiDaoNum+" 是否已被调度:"+this.isVisited;  
  17.     }  
  18.   
  19.     public PCB(int id, int ciDaoNum, boolean isVisited) {  
  20.         super();  
  21.         this.id = id;  
  22.         CiDaoNum = ciDaoNum;  
  23.         this.isVisited = isVisited;  
  24.     }  
  25. }  
  26.   
  27. public class Main {  
  28.     public static Scanner scanner = new Scanner(System.in);  
  29.     public static TreeSet<PCB> pcbsOut = new TreeSet<PCB>(new Comparator<PCB>() {  
  30.         @Override  
  31.         public int compare(PCB p1, PCB p2) {  
  32.             if (p1.CiDaoNum >= p2.CiDaoNum)  
  33.                 return 1;  
  34.             return -1;  
  35.         }  
  36.   
  37.     });  
  38.     public static TreeSet<PCB> pcbsIn = new TreeSet<PCB>(new Comparator<PCB>() {  
  39.         @Override  
  40.         public int compare(PCB p1, PCB p2) {  
  41.             if (p1.CiDaoNum >= p2.CiDaoNum)  
  42.                 return -1;  
  43.             return 1;  
  44.         }  
  45.   
  46.     });  
  47.     public static Random random = new Random();  
  48.     public static boolean isOutDirection;  
  49.     public static int currentCiDaoNum;  
  50.     public static int Count;  
  51.   
  52.     public static void main(String[] args) {  
  53.         // 初始化工作  
  54.         int originalNum = random.nextInt(4) + 4;  
  55.         Count = originalNum;  
  56.         for (int i = 1; i <= originalNum; i++) {  
  57.             PCB temp = new PCB(i, random.nextInt(200) + 1false);  
  58.             pcbsOut.add(temp);  
  59.             pcbsIn.add(temp);  
  60.         }  
  61.         System.out.println("请求I/O表中已经有以下进程项:");  
  62.         Iterator<PCB> iterator = pcbsOut.iterator();  
  63.         while (iterator.hasNext()) {  
  64.             System.out.println(iterator.next());  
  65.         }  
  66.         isOutDirection = random.nextInt(200) > 100 ? true : false;  
  67.         System.out.println("当前移臂方向为:" + (isOutDirection ? "从内向外" : "从外向内"));  
  68.         currentCiDaoNum = random.nextInt(200) + 1;  
  69.         System.out.println("当前所访问的磁道为:" + currentCiDaoNum );  
  70.   
  71.         System.out.println();  
  72.         System.out.println();  
  73.   
  74.         boolean isGoOn = true;  
  75.         while (isGoOn) {  
  76.             System.out.println("请输入一个0~1的随机数,小于等于0.5表示进行磁盘调度,大于0.5表示进行新进程的请求接收:");  
  77.             double ran = scanner.nextDouble();  
  78.             if (ran <= 0.5)  
  79.                 CiPanDiaoDu();  
  80.             else  
  81.                 JieShouQingQiu(originalNum + 1);  
  82.             System.out.println("----------------------------");  
  83.         }  
  84.     }  
  85.   
  86.     private static void JieShouQingQiu(int id) {  
  87.         System.out.println("请输入进程要访问的磁道号(保证磁道号在1~200内且不要与现有进程的磁道号重复):");  
  88.         int Num = scanner.nextInt();  
  89.         PCB temp = new PCB(id, Num, false);  
  90.         pcbsOut.add(temp);  
  91.         pcbsIn.add(temp);  
  92.         Count++;  
  93.         System.out.println("该进程已被成功添加至请求I/O表!!");  
  94.         System.out.println();  
  95.         System.out.println();  
  96.         System.out.println("目前请求I/O表已经具备以下表项:");  
  97.         Iterator<PCB> iterator = pcbsOut.iterator();  
  98.         while (iterator.hasNext()) {  
  99.             System.out.println(iterator.next());  
  100.         }  
  101.         System.out.println("此时磁臂方向为:" + (isOutDirection ? "从内向外" : "从外向内") + ".");  
  102.         System.out.println("此时磁臂所在磁道的号码为:" + currentCiDaoNum );  
  103.           
  104.     }  
  105.   
  106.     private static void CiPanDiaoDu() {  
  107.         if (Count <= 0) {  
  108.             System.out.println("请求I/O表已空,请添加请求后再进行磁盘调度或者退出程序。");  
  109.             return;  
  110.         }  
  111.         System.out.println("开始在" + currentCiDaoNum + "磁道上并" + (isOutDirection ? "从内向外" : "从外向内") + "上查询--");  
  112.         Iterator<PCB> iterator = null;  
  113.         boolean isFindWithOneDirection = false;  
  114.         PCB mindPCB = null;  
  115.         if (isOutDirection) {  
  116.             iterator = pcbsOut.iterator();  
  117.             while (iterator.hasNext()) {  
  118.                 PCB pcb = iterator.next();  
  119.                 // 从内向外找,跳过已经找调度过的进程  
  120.                 if (pcb.isVisited)  
  121.                     continue;  
  122.                 // 当磁道号小于磁臂所在的磁道号时,一直向外遍历寻找  
  123.                 if (pcb.CiDaoNum < currentCiDaoNum) {  
  124.                     mindPCB = pcb;  
  125.                     continue;  
  126.                 }  
  127.                 // 只要找到一个大于等于磁臂所在的磁道号的进程时,就立马退出  
  128.                 isFindWithOneDirection = true;  
  129.                 mindPCB = pcb;  
  130.                 break;  
  131.             }  
  132.             if (!isFindWithOneDirection)  
  133.                 isOutDirection = false;  
  134.         } else  
  135.         // 磁臂从外向内  
  136.         {  
  137.             iterator = pcbsIn.iterator();  
  138.             while (iterator.hasNext()) {  
  139.                 PCB pcb = iterator.next();  
  140.                 // 从内向外找,跳过已经找调度过的进程  
  141.                 if (pcb.isVisited)  
  142.                     continue;  
  143.                 // 当磁道号小于磁臂所在的磁道号时,一直向外遍历寻找  
  144.                 if (pcb.CiDaoNum > currentCiDaoNum) {  
  145.                     mindPCB = pcb;  
  146.                     continue;  
  147.                 }  
  148.                 // 只要找到一个大于等于磁臂所在的磁道号的进程时,就立马退出  
  149.                 isFindWithOneDirection = true;  
  150.                 mindPCB = pcb;  
  151.                 break;  
  152.             }  
  153.             if (!isFindWithOneDirection)  
  154.                 isOutDirection = true;  
  155.   
  156.         }  
  157.         // 上述while循环退出时,没找到时pcb为反方向上距离currentCiDaoNum最近的没被访问的进程  
  158.         // 找到时pcb为磁臂方向上离currentCiDaoNum最近的没被访问的进程  
  159.   
  160.         // 当mindPCB为空时表明所有磁道号均大于磁臂所在的磁道号,这时取pcbsOut第一个元素即可  
  161.         if (mindPCB == null) {  
  162.             mindPCB = pcbsOut.first();  
  163.         }  
  164.         if (!isFindWithOneDirection) {  
  165.             System.out.println("在当前方向上没有查询到,转变磁臂方向查找," + "找到在" + mindPCB.CiDaoNum + "磁道上且进程编号为" + mindPCB.id + "的进程。");  
  166.         } else {  
  167.             System.out.println("在当前方向上找到符合要求的进程," + "其所在磁道号为:" + mindPCB.CiDaoNum + ",进程编号为:" + mindPCB.id);  
  168.         }  
  169.         mindPCB.isVisited=true;  
  170.         currentCiDaoNum = mindPCB.CiDaoNum;  
  171.         Count--;  
  172.         System.out.println("此时磁臂方向为:" + (isOutDirection ? "从内向外" : "从外向内") + ".");  
  173.         System.out.println("此时磁臂所在磁道的号码为:" + currentCiDaoNum );  
  174.     }  
  175. }  

以下我的运行结果截图:




PS:前几天就已经写好的程序,一直到现在才想起来写博客,我这拖延的坏毛病得改啊,最近复习的也挺紧张,坚持~


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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

苹果主屏幕按钮怎么设置_苹果手机屏幕变大怎么恢复

如果苹果手机屏幕放大起来&#xff0c;其实只要同时使用三个手指快速连续点击手机屏幕两次&#xff0c;手机界面就会恢复正常。还可以在【设置】-【通用】-【辅助功能】中将【缩放】开关关闭。在【辅助功能】中【更大字体】选项中可以调整字体的大小。具体介绍如下&#xff1a;…

苹果主屏幕按钮怎么设置_Mac小技巧 Mac屏幕旋转怎么设置

相信不少的Mac用户在躺下看电子书或者电影的时候&#xff0c;都希望可以将Mac的电脑屏幕进行旋转&#xff01;其实&#xff0c;这个操作是可以实现的呢&#xff01;那么&#xff0c;你知道Mac屏幕旋转怎么设置吗&#xff1f;想要知道答案的话就快来阅读下面的文章吧&#xff01…

苹果屏幕旋转怎么设置_iPhone12屏幕供应商是谁 苹果12屏幕怎么查看是哪家

苹果iPhone12系列手机在10月份正式发售上市&#xff0c;今年的iPhone12全系列都使用了OLED屏幕&#xff0c;官方将这块屏幕称之为超视网膜 XDR 显示屏&#xff0c;那么今年的iPhone12系列屏幕供应商有哪些&#xff0c;怎么分辨自己手上的iPhone12屏幕来自哪家公司呢&#xff0c…

苹果手机投屏软件_苹果手机怎样投屏到笔记本?

注&#xff1a;本文转载自网络&#xff0c;不代表本平台立场&#xff0c;仅供读者参考&#xff0c;著作权属归原创者所有。我们分享此文出于传播更多资讯之目的。如有侵权&#xff0c;请在后台留言联系我们进行删除&#xff0c;谢谢&#xff01; 经常用手机的小伙伴都知道&am…

怎么设置苹果手机的小圆点_苹果屏幕旋转怎么设置?关于苹果手机设置的一些小技巧...

苹果屏幕旋转怎么设置&#xff1f;在平常使用手机观看视频的时候&#xff0c;很多人希望手机屏幕可以自己旋转为横屏状态&#xff0c;在使用微信聊天的时候再自动转为竖屏&#xff0c;这种切换可以直接利用控制中心的一个功能来实现。 如何开启苹果手机的屏幕旋转&#xff1f;首…

苹果屏幕使用时间怎么设置_苹果手机屏幕不能旋转怎么办

很多刚刚接触苹果手机的人&#xff0c;可能不知道怎么使用苹果手机。那么苹果手机屏幕不能旋转怎么办呢&#xff1f;下面就让小编来告诉大家吧&#xff0c;欢迎阅读。 1、苹果手机页面未锁定的情况下从屏幕底端向上滑动&#xff0c;弹出小界面窗口。 2、可以看到小窗口顶部左端…

linux屏幕旋转后触控不准,手机重力感应失效解决方法 不能自动旋转屏幕怎么设置...

如今手机已经成为人们生活中必不可少的一个工具了&#xff0c;在使用过程也常常会遇到各种各样的问题&#xff0c;比如当手机重力感应失效的时候应该怎么解决呢&#xff0c;手机不能自动旋转屏幕要怎么设置&#xff0c;针对这个问题下面就为大家带来最新解决方法&#xff0c;希…

苹果6怎样打开html,苹果6屏幕旋转怎么设置 怎么开启和关闭【图文】

手机在使用的过程中&#xff0c;通常都会有两种状态&#xff0c;横屏与竖屏&#xff0c;大家的使用习惯不一样&#xff0c;所喜欢的状态也不一样&#xff0c;而且手机都会有屏幕自动旋转的情况&#xff0c;它会根据手机的摆放状态自己切换&#xff0c;比较方便大家使用&#xf…

会员管理系统,建议收藏!

你见过会员管理系统吗&#xff1f;在一些线下的美容院&#xff0c;健身房&#xff0c;理发店&#xff0c;往往会有办理会员这样的需求&#xff0c;所以会员管理系统应运而生。那会员管理系统有哪些作用呢&#xff1f; 会员卡&#xff1a;无需填写信息、无需实体会员卡&#xf…

会员卡系统的管理运营

下面的是会员系统的源代码和DOS命令的运行

会员卡应用管理系统源码 支持收银+积分管理+商城营销功能 含详细搭建教程

分享一个会员卡应用管理系统源码&#xff0c;收银积分管理商城营销系统源码&#xff0c;含完整的程序包和搭建教程。 系统功能一览&#xff1a; 1、精简强悍&#xff0c;会员卡&#xff0c;积分&#xff0c;在线充值&#xff0c;商家核销&#xff0c;在线下单&#xff0c;优惠…

C语言:会员管理系统

会员信息包括&#xff1a;会员号&#xff08;6位数&#xff0c;唯一&#xff09;&#xff0c;姓名&#xff0c;身份证号&#xff0c;联系电话&#xff0c;状态&#xff08;1表示正常&#xff0c;0表示挂失&#xff09;。 会员管理包括&#xff1a;会员的添加、删除、修改&#…

云上铺会员管理系统支持什么类型会员卡?

最近很多打算购买我们系统的客户都在问我们&#xff0c;云上铺到底支持什么会员卡&#xff0c;今天趁这个机会专门给大家讲一下。 云上铺会员管理系统&#xff0c;作为一款独立开发设计的SAAS会员管理系统&#xff0c;广泛适用于美容美发&#xff0c;汽车美容&#xff0c;服装…

C语言 会员管理系统

大一上学期期末项目设计&#xff1b; 思路参考&#xff1a;【千锋教育新版C语言程序设计视频教程&#xff08;适合自学&#xff0c;c语言初学者入门教程&#xff09;】 https://www.bilibili.com/video/BV1id4y1375a/?p119&share_sourcecopy_web&vd_sourcea6401c9820…

微信会员卡管理系统会员充值说明

云上铺微信会员卡管理系统会员充值即会员卡储值进行余额消费一种操作。 基础操作&#xff1a;点击【消费收银】→【会员充值】&#xff0c;显示有【会员充值/扣款/转账/提现】等业务&#xff0c;如下图所示&#xff1a; 会员充值必须先选择会员信息,输入会员卡号&#xff0c;或…

超市VIP卡管理系统

好久没有碰VS了。。。只好自己找个项目练手。 今天找了个练习的项目&#xff0c;超市VIP卡管理系统。 拿到手的项目需求就这么点。 &#xff08;1&#xff09; 会员卡使用磁卡&#xff0c;允许手工输入卡号和扫描器输入两种方式。会员卡号的长度为10位&#xff0c;前两位是各分…

自己开店怎么办会员卡-云上铺会员管理系统

现在的生意是越来越不好做&#xff0c;很多实体商家为了增加门店人气策划了很多引流活动。刚开始人气虽然上涨得很快&#xff0c;但客户的流失率也非常的高。因此&#xff0c;实体商家希望通过会员卡来留住消费的客户&#xff0c;但开店办会员的会员卡怎么办呢&#xff1f; ​ …

超市会员管理系统

目录 一、需求分析 二、问题描述 三、总体设计 四、详细设计 1&#xff09;数据类型 2) 函数名 3&#xff09;登陆界面 4&#xff09;主界面 5&#xff09;界面设计 &#xff08;1&#xff09;系统说明 &#xff08;2&#xff09; 输入会员信息 &#xff08;3&#xff09; 显示…

电子会员卡管理系统卡具配置

一.登录精通后台系统 1. 进行指定主机的卡具设置 1&#xff09; 点击【主机维护】选项 登录成功后&#xff0c;点击【主机维护】项进入主机维护界面&#xff1a; 2&#xff09; 选择主机 ①选中需要设置的主机&#xff0c;②点击右侧的【卡具设置】按钮&#xff1a; 3&#xff…