TIT 操作系统实验二 磁盘调度算法(FCFS、SSTF、SCAN)

实验二 磁盘调度

前言

  • 参考教材《操作系统 第四版》汤小丹

  • 因为实验要求为了更好地模拟和评价算法的性能,随机产生需寻道的磁道序列,以磁道序列的首磁道为磁头的当前位置;在SCAN算法中,允许用户指定当前寻道方向;随机产生数据不方便对比,所以做了两份代码(一种随机产生磁道序列以磁道序列的首磁道为磁头的当前位置(这里命名为A)即实验内容,一种自定义磁道序列自定义磁头位置(这里命名为B)),完整代码放在文末了,方便对比

  • SCAN算法做出了两种方法,分别写在了固定磁头位置和自定义磁头位置

  • 虽然只做了三种,循环算法大同小异,搞懂前三个,其它算法很好编写

实验目的

编程模拟实现磁盘调度的常用算法或调试分析相关磁盘调度程序,加深对磁盘调度常用算法的理解和实现技巧

实验内容

1.自定义磁盘调度相关的数据结构

2.依据先来先服务算法(FCFS)、最短寻道优先算法(SSTF)、扫描(SCAN,也称电梯)算法的原理,编写对应函数,模拟系统的磁盘调度服务;

3.为了更好地模拟和评价算法的性能,随机产生需寻道的磁道序列,以磁道序列的首磁道为磁头的当前位置;在SCAN算法中,允许用户指定当前寻道方向;

4.统计以上算法总寻道次数和平均寻道距离;

比较/分析以上算法的寻道性能,并作出自己的评价

实验步骤

冒泡排序

先写一个冒泡排序,在后面调用会使用到

// 冒泡排序(从小到大)
public static void SortA(int[] list){
   
    for (int i = 0; i < list.length - 1; i++) {
   
        for (int j = 0; j < list.length - 1 - i; j++) {
   
            if (list[j] > list[j + 1]) {
   
                int temp = list[j];
                list[j] = list[j + 1];
                list[j + 1] = temp;
            }
        }
    }
}

// 冒泡排序(从大到小)
public static void SortB(int[] list) {
   
    for (int i = 0; i < list.length - 1; i++) {
   
        for (int j = 0; j < list.length - 1 - i; j++) {
   
            if (list[j] < list[j + 1]) {
   
                int temp = list[j];
                list[j] = list[j + 1];
                list[j + 1] = temp;
            }
        }
    }
}

先来先服务FCFS

A

// 先来先服务FCSFS,即根据磁盘访问的先后次序进行调度,遍历list数组即可,所以不做赘述
private static void FCFS(int[] list) {
   
    System.out.println("磁道开始位置为" + list[0]);

    int num = 0;// 变量num记录寻道距离
    for (int j = 0; j < list.length - 1; j++) {
   
        num += Math.abs(list[j + 1] - list[j]);
    }
    System.out.println("磁盘扫描序列为:" + Arrays.toString(list));
    System.out.println("寻道次数:" + num);
    double w = ((float) num / (float) list.length);
    System.out.println("平均寻道距离:" + w);
}

B

// 先来先服务FCSFS,即根据磁盘访问的先后次序进行调度,遍历list数组即可,所以不做赘述
private static void FCFS(int[] list) {
   
    int i = 0;
    System.out.println("请输入磁头初始位置");
    Scanner sc = new Scanner(System.in);
    i = sc.nextInt();
    int num = 0;// 变量num记录寻道距离
    num = Math.abs(i - list[0]);
    for (int j = 0; j < list.length - 1; j++) {
   
        num += Math.abs(list[j + 1] - list[j]);
    }
    System.out.println("磁盘扫描序列为:" + Arrays.toString(list));
    System.out.println("寻道次数" + num);
    double w = ((float) num / (float) list.length);
    System.out.println("平均寻道距离" + w);
}

最短寻道时间优先SSTF

// 最短路径算法SSTF,即访问下一个磁道前,先计算一次当前磁头到访问各个磁道的距离
private static void SSTF(int[] list) {
   
    int[] list1=new int[list.length];//因为下面修改了list,再次运行算法3时,list数组已经被修改,所以这里把值传给list1
    System.arraycopy(list,0, list1, 0, list.length);
    int i = list1[0];// 变量i记录当前磁头位置
    System.out.println("磁道开始位置为" + list1[0]);
    int num = 0;// num记录总寻道距离
    int[] k = new int[list1.length];// k数组记录访问的每一个磁道到磁头距离
    int[] templist = new int[list1.length];// 将结果保存在templist[]中

    for (int a = 0; a < list1.length; a++) {
   
        // j循环遍历出每一个访问的磁道到当前磁头的距离保存在k数组中
        for (int j = 0; j < list1.length; j++) {
   
            k[j] = Math.abs(list1[j] - i);
        }
        // 将k数组赋值给temp数组,对temp数组冒泡排序
        int[] temp = new int[k.length];
        for (int j = 0; j < k.length; j++) {
   
            temp[j] = k[j];
        }
        SortA(temp);

        int j = temp[0];// 找到磁头到下一个磁道距离最小的为temp[0]

        // 循环遍历找到temp[0]在list磁道序列数组中的位置
        for (int t = 0; t < k.length; t++) {
   
            // if语句找到list[t]到当前磁头最近
            if (k[t] == j) {
   
                i = list1[t];// 变量i记录磁头位置
                templist[a] = i;// 将结果存入templist数组中
                list1[t] = 999999;// 将第g个磁道号设为999999,可以理解为权重设为99999,这样他在下一次遍历,在k数组中总是最大
                break;
            }
        }
        num += j;
    }
    System.out.println("磁盘扫描序列为:" + Arrays.toString(templist));
    System.out.println("寻道次数:" + num);
    double w = ((float) num / (float) list.length);
    System.out.println("平均寻道距离:" + w);
}

B

// 最短路径算法SSTF,即访问下一个磁道前,先计算一次当前磁头到访问各个磁道的距离
private static void SSTF(int[] list) {
   
    int i = 0;// 变量i记录当前磁头位置
    int num = 0;// num记录总寻道距离
    int[] templist = new int[list.length];// 将结果保存在templist[]中
    int[] k = new int[list.length];// k数组记录访问的每一个磁道到磁头距离
    System.out.println("请输入磁头初始位置");
    Scanner sc = new Scanner(System.in);
    i = sc.nextInt();

    for (int a = 0; a < list.length; a++) {
   
        // j循环遍历出每一个访问的磁道到当前磁头的距离保存在k数组中
        for (int j = 0; j < list.length; j++) {
   
            k[j] = Math.abs(list[j] - i);
        }

        // 将k数组赋值给temp数组,对temp数组冒泡排序
        int[] temp = new int[k.length];
        for (int j = 0; j < k.length; j++) {
   
            temp[j] = k[j];
        }
        SortA(temp);

        int j = temp[0];// 找到磁头到下一个磁道距离最小的为temp[0]

        // 循环遍历找到temp[0]在list磁道序列数组中的位置
        for (int t = 0; t < k.length; t++) {
   
            // if语句找到list[t]到当前磁头最近
            if (k[t] == j) {
   
                i = list[t];// 变量i记录磁头位置
                templist[a] = i;// 将结果存入templist数组中
                list[t] = 999999;// 将第g个磁道号设为999999,可以理解为权重设为99999,这样他在下一次遍历,k数组中总是最大
                break;
            }
        }
        num += j;
    }
    System.out.println("磁盘扫描序列为:" + Arrays.toString(templist));
    System.out.println("寻道次数:" + num);
    double w = ((float) num / (float) list.length);
    System.out.println("平均寻道距离:" + w);
}

扫描算法SCAN

写完扫描算法准备关机的时候,突然想到了另一种排序方法,B的第42行else语句中,好像可以修改修改。所以对A进行了修改。对A简单修改还可以实现CSCAN循环扫描算法,我认为A中的算法更容易理解其中的原理,所以下面着重解释!

A

/*
	 * 扫描算法SCAN 磁盘的0磁道在最外圈 扫描算法又叫电梯算法,即按从小到大或从大到小的顺序去依次访问磁道。
	 * 所以这里分两种情况,1.寻道从内向外(从大到小) 2.寻道从外向内(从小到大)
	 * 
	 * 
	 * 1.若当前磁头位置大于请求序列中最大者 2.若当前磁头位置小于请求序列中最小者 3.若当前磁道号大于请求序列中最小者且小于最大者
	 * 这里用同一个函数去解决三种情况
	 */
private static void SCAN(int[] list) {
   
    int[] list1=new int[list.length];//因为下面修改了list,再次运行算法3时,list数组已经被修改,所以这里把值传给list1
    System.arraycopy(list,0, list1, 0, list.length);
    Scanner sc = new Scanner(System.in);
    int k = list1[0];// 变量i记录当前磁头位置
    int tempk1 = 0;
    int tempk2 = 0;
    int flag=1;
    int num = 0;// num记录总寻道距离
    int[] templist = new int[list1.length];// 将访问顺序存入templist中
    System.out.println("磁道开始位置为:" + list1[0]);
    //while中先计算出磁道访问的顺序
    while (true) {
   
        System.out.println("1.磁头从外向内  2.磁头从内向外");
        int choice = sc.nextInt();

        if (choice == 1) {
   
            flag
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值