热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

操作系统之基于扫描的磁盘调度扫描(SCAN)算法循环扫描(CSCAN)算法

磁盘调度二实验内容:编写一个程序处理磁盘调度中寻道时间的策略。实验目的:磁盘调度中寻道时间直接影响到数据访问的快慢,处理好磁盘寻道时间是关键。实验题目:采用SCAN策略处理;采用C

磁盘调度二

实验内容:编写一个程序处理磁盘调度中寻道时间的策略。

实验目的:磁盘调度中寻道时间直接影响到数据访问的快慢,处理好磁盘寻道时间是关键。

实验题目:



  • 采用SCAN策略处理;

  • 采用CSCAN策略处理;


实验原理


扫描(SCAN)算法

进程“饥饿”现象



  • SSTF 算法虽然能获得较好的寻道性能, 但却可能导致某个进程发生“饥饿” (Starvation) 现象,其实质上是基于优先级的调度算法。因为只要不断有新进程的请求到达, 且其所要访问的磁道与磁头当前所在磁道的距离较近,这种新进程的 I/O 请求必须优先满足。对 SSTF 算法略加修改后所形成的 SCAN 算法, 即可防止老进程出现“饥饿”现象。



  • SCAN 算法(电梯调度算法)不仅考虑欲访问的磁道与当前磁道的距离,更优先考虑磁 头的当前移动方向。磁头沿一个方向移动,直至该方向上无新的磁道访问请求,才将磁臂换向,为反方向上的磁道访问请求服务。

    磁道距离 + 磁头移动方向



  • 优点:较好的寻道性能,且能防止进程饥饿



  • 缺点:严重推迟某些进程的请求




循环扫描(CSCAN)算法



  • Scan 算法的特例:磁头刚移过某磁道 T ,该位置有访问请求,但磁头移动方向上不断有新的请求,则磁道 T 上的访问请求被严重推后。 改进SCAN算法方式:

    • 磁头单向移动

    • 循环扫描




代码实现


数据结构和符号说明



  • diskCollection ArrayList类型数据,为初始的磁道号序列

  • start int类型数据,为磁道开始,默认向磁道号增加的方向访问

  • timeList ArrayList类型数据,为访问磁道对应的移动距离

  • distanceSum int类型数据,磁针寻道总道数

  • diskList ArrayList类型数据,为排序好的磁道访问顺序

  • diskListBefore ArrayList类型数据,为磁针优先访问的磁道序列 由里向外访问顺序

  • diskListAfter ArrayList类型数据,为磁针后访问的磁道序列 由外向里访问顺序


ScanDisk公共类

package com.process.diskscan;
import java.util.ArrayList;
/**
* @Author: SKPrimin
* @Date 2021/12/18 16:12
* @ClassName: ScanDisk
* @Description: TODO 扫描算法与循环扫描的公共类 定义变量结构和分组方法
*/
public class ScanDisk {
/**
* diskCollection ArrayList类型数据,为初始的磁道号序列
*/
protected ArrayList diskCollection;
/**
* start int类型数据,为磁道开始,默认向磁道号增加的方向访问
*/
protected int start;
/**
* timeList ArrayList类型数据,为访问磁道对应的移动距离
*/
protected ArrayList movList = new ArrayList<>();
/**
* distanceSum int类型数据,磁针寻道总道数
*/
protected int distanceSum;
/**
* diskList ArrayList类型数据,为排序好的磁道访问顺序
*/
protected ArrayList diskList = new ArrayList<>();
/**
* diskListBefore ArrayList类型数据,为磁针优先访问的磁道序列 由里向外访问顺序
*/
protected ArrayList diskListBefore = new ArrayList<>();
/**
* diskListAfter ArrayList类型数据,为磁针后访问的磁道序列 由外向里访问顺序
*/
protected ArrayList diskListAfter = new ArrayList<>();
/**
* separate分割方法,以起始点为分界线,将磁道分为前后连个顺序
*/
protected void separate() {
// 遍历 diskCollection
for (int item : diskCollection) {
// 若在起始点外边在第一轮访问
if (item > start) {
diskListBefore.add(item);
// 在起始点里边则在后一轮访问
} else {
diskListAfter.add(item);
}
}
}
/**
* 计算距离函数通过三元运算符返回两数绝对值
*
* @param a 一个位置
* @param b 另一个点位置
* @return 两个位置之间的距离
*/
protected int distance(int a, int b) {
return a > b ? a - b : b - a;
}
/**
* 排序函数
*
* @param arrayList 要排序的数组列表
* @param reverse 是否逆序 false为升序,true为逆序
* @return 返回已经排序好的数组列表
*/
public ArrayList sort(ArrayList arrayList, boolean reverse) {
int len = arrayList.size();
for (int i = 0; i int index = i;
for (int j = i + 1; j // 若 reverse为false 升序排序 reverse为true则降序排序
if (!reverse) {
if (arrayList.get(j) index = j;
}
} else {
if (arrayList.get(j) > arrayList.get(index)) {
index = j;
}
}
}
//位置交换 将较小reverse=false /较大reverse=true 的数提到前边
int temp = arrayList.get(index);
arrayList.set(index, arrayList.get(i));
arrayList.set(i, temp);
}
return arrayList;
}
public void calculateTravelDistance() {
// 定义磁盘针头
int pinhead = start;
// 计算访问磁道号时的移动距离
for (int i = 0; i // 将对应位置设置为距离 并统计总数
movList.add(distance(pinhead, diskList.get(i)));
distanceSum += movList.get(i);
pinhead = diskList.get(i);
}
}
}

SCAN实现类

package com.process.diskscan;
import java.util.ArrayList;
/**
* @Author: SKPrimin
* @Date 2021/12/18 16:08
* @ClassName: SCAN
* @Description: TODO 扫描算法的实现类
*/
public class SCAN extends ScanDisk {
/**
* 扫描算法构造器
*
* @param diskCollection 即将访问的磁道号数组列表
* @param start 磁针起始点
*/
public SCAN(ArrayList diskCollection, int start) {
this.diskCollection = diskCollection;
this.start = start;
}
/**
* 执行此次扫描算法的调动方法
*/
public void run() {
//调用父类的分类方法
separate();
// diskList接收排序好的顺序
diskList = sort(diskListBefore, false);
diskList.addAll(sort(diskListAfter, true));
// 计算移动距离
calculateTravelDistance();
}
@Override
public String toString() {
return "\n扫描(SCAN)算法" +
"\n从" + start + "号磁道开始" +
"\n被访问的下一个磁道号\t" + diskList +
"\n移动距离(磁道数)\t" + movList +
"\n总道数:" + distanceSum + "\t平均寻道长度:" + String.format("%.2f", (double) distanceSum / movList.size());
}
}

CSCAN实现类

package com.process.diskscan;
import java.util.ArrayList;
/**
* @Author: SKPrimin
* @Date 2021/12/18 17:24
* @ClassName: CSCAN
* @Description: TODO
*/
public class CSCAN extends ScanDisk {
/**
* 扫描算法构造器
*
* @param diskCollection 即将访问的磁道号数组列表
* @param start 磁针起始点
*/
public CSCAN(ArrayList diskCollection, int start) {
this.diskCollection = diskCollection;
this.start = start;
}
/**
* 执行此次扫描算法的调动方法
*/
public void run() {
//调用父类的分类方法
separate();
// diskList接收排序好的顺序
diskList = sort(diskListBefore, false);
diskList.addAll(sort(diskListAfter, false));
// 计算移动距离
calculateTravelDistance();
}
@Override
public String toString() {
return "\n循环扫描(CSCAN)算法" +
"\n从" + start + "号磁道开始" +
"\n被访问的下一个磁道号\t" + diskList +
"\n移动距离(磁道数)\t" + movList +
"\n总道数:" + distanceSum + "\t平均寻道长度:" + String.format("%.2f", (double) distanceSum / movList.size());
}
}

测试类

package com.process.diskscan;
import java.util.ArrayList;
/**
* @Author: SKPrimin
* @Date 2021/12/18 17:27
* @ClassName: Test
* @Description: TODO 基于扫描的磁盘调度算法
*/
public class Test {
public static void main(String[] args) {
// 磁盘号顺序
int[] track = new int[]{55, 58, 39, 18, 90, 160, 150, 38,184};
ArrayList ta = new ArrayList<>();
for (int t : track) {
ta.add(t);
}
// 先来先服务
SCAN ff = new SCAN( ta,100);
ff.run();
System.out.println(ff);
//最短寻道时间优先
CSCAN st = new CSCAN( ta,100);
st.run();
System.out.println(st);
}
}

运行截图

CSCAN运行效果截图



推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
author-avatar
936383130_54f13e
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有