磁盘调度算法FCFS、SSTF、SCAN、CSCAN详解

常见的磁盘调度算法有:

1.FCFS:先来先服务算法;

2.SSTF:最短寻道时间算法;

3.SCAN:扫描算法(也叫电梯调度算法);

4.CSCAN:循环扫描算法

算法的详细介绍:

  • FCFS:算法思想非常简单,就是不论初始磁头在什么位置,都是按照服务队列的先后顺序依次处理进程,可以类比队列的先进先出。优点是进程处理起来非常简单,但缺点显而易见,就是平均寻道长度会很长。

Java实现:

public class fcfs {
    Scanner x=new Scanner(System.in);
    public int[] position;
    public int num;
    public fcfs()
    {
        System.out.println("Enter the number of process:");
        num=x.nextInt();
        position=new int[num];
    }
    public void input()
    {
        int i=0;
        for(i=0;i<num;i++)
            position[i]=x.nextInt();
    }
    public void algo()
    {
        int i=1;
        for(i=1;i<=num;i++)
            System.out.println("Process Accessed "+i+" at "+position[i-1]);
    }
}
  • SSTF:最短寻道时间算法,算法本质是贪心,已知磁头的初始位置,则最先被处理就是距离磁头位置最近的进程,处理完成后再处理距离当前磁道最近的进程,直到所有的进程被处理。该算法的优点是平均寻道长度会大大减少,缺点是距离初始磁头较远的服务长期得不到处理,产生“饥饿”现象。具体的思路是:通过循环寻找与初始磁头最近的进程,将进程处理,然后将该进程标记为-1,将初始磁头移动到该进程所在的磁道。然后依次类推,标记为-1的进程不再参与,知道所有的进程都被标记为-1,磁盘调度完成。

Java实现

public class sstfAlg{
    int num;
    int[][] position;
    int size;
    int initPos;
    int[] sequenceOfProcess ;//存储访问序列
    int[] sequenceOfNumber;
    Scanner sc = new Scanner(System.in);
    public sstfAlg(int a,int b,int c){
        //a means the amount of process
        //b means the inital of position
        //c means the size of disk
        num = a;
        position = new int[a][2];
        sequenceOfProcess = new int[a];
        sequenceOfNumber = new int[a];
        initPos = b;
        size = c;
    }
    public void input(){
        System.out.println("input the number of process:");
        for(int i=0;i<num;i++){
            position[i][0] = sc.nextInt();
            position[i][1] = i+1;
        }
    }
    public void myAlg(){
        int nearest = 10000;
        int index = 0 ;
        int initPos1 = initPos;
        //复制一个数组用来寻找访问序列
        int[][] position1 = new int[num][2];
        for(int i=0 ;i<num;i++){
            position1[i][0] = position[i][0];
            position1[i][1] = i+1;
        }
        //寻找磁头访问的序列        
        for(int i=0;i<num;i++){
            for(int j=0;j<num;j++){
                if(position1[j][0]!=-1){
                    if(Math.abs(initPos1 - nearest)>Math.abs(position1[j][0]-initPos1)){
                        nearest = position1[j][0];
                        index = j;
                    }    
                }
            }
            sequenceOfProcess[i] = nearest;
            sequenceOfNumber[i] = index+1;
            position1[index][0] = -1;//-1表示此位置的进程已经放在了访问序列,不在进行查询
            initPos1 = nearest;
            nearest = 10000;        
        }
        
        for(int i=0;i<num;i++){
            System.out.println("进程"+sequenceOfNumber[i]+"在磁道"+sequenceOfProcess[i]+"完成");
        }
    }
  • SCAN:磁头仅沿一个方向进行扫描,在扫描途中完成所有没有完成的请求,直到磁头到达磁盘在这个方向上的最后一个磁道或者这个方向上最后一个请求所在的磁道。利用数组存储进程和磁道编号,依据给定的初始磁头,先找到初始磁头在哪两个进程之间,然后向内扫描。当磁头扫描到磁盘最内层即磁道0且进程还没有全部被处理,磁头开始向外扫描,直到所有的进程都完成。

Java实现

class scanAlgo{
    Scanner sc = new Scanner(System.in);
    int num;   //进程数量
    int[] position1; 
    int initPos;  //磁头初始位置
    public scanAlgo(){
        System.out.println("input the amount of process:");
        num = sc.nextInt();
        position1 = new int[num+1];
        System.out.println("input the initial position:");
        initPos = sc.nextInt();
        
    }
    public void input(){
        System.out.println("input the number of process:");
        for(int i=0;i<num;i++){
            position1[i] = sc.nextInt(); //记录进程所在的磁道号
        }
    }
    public void adjust(){
        //按照磁道编号将进程排序,就是一个冒泡排序
        for(int i=0;i<num;i++){
            for(int j=1;j<num-i;j++){
                if(position1[j-1] > position1[j]){
                    int temp = position1[j];
                    position1[j] = position1[j-1];
                    position1[j-1] = temp;
                }
            }
        }       
    }
     public void algo(){
         //寻找磁头初始位置在哪两个进程之间
         input();
         adjust();
         int init;  
        for(init=0;init<num-1;init++){
             if(position1[init] <= initPos && position1[init+1] > initPos)
                 break;
             //此时得到的init值就是磁头初始位置
         }
         int start  = init;
         //磁头先向里扫描
         for(int i=start;i>=0;i--){
             System.out.println("The First Time Scan:"+"Process"+position[i][1]+"At Position"+position[i][0]+"Completed");
             }
         }
         //磁头开始从初始位置向外扫描
         if(position1[init+1]!=0){
             System.out.println("This Is the Track 0");
             }
             for(int i=start+1;i<num;i++){
                System.out.println("The Second Time Scan:"+"Process"+position[i][1]+"At Position"+position[i][0]+"Completed");
             }
         }
     }  
}
  • CSCAN:在磁盘扫描算法的基础上改变磁头的扫描路径:扫描到最内层之后从最外层向内继续扫描,即扫描方向一致。该算法的思路与扫描算法基本一致,也使用二维数组进行进程编号和进程所在磁道号的存储,算法的不同之处在于当磁头扫描到磁盘的最内层时,磁头跳转到磁盘最外层重新向内扫描,这样就可以有效的避免将已经扫描过的磁道重新扫描一次,降低了平均寻到距离。

Java实现

class cscanAlg{
    Scanner sc = new Scanner(System.in);
    int num;
    int[][] position ;
    int initPos;
    int size;
    public cscanAlg (){
        System.out.println("input the amount of process:");
        num = sc.nextInt();
        position = new int[num+1][2];
        System.out.println("input the initial position :");
        initPos = sc.nextInt();    
        System.out.println("input the size of Disk:");
        size = sc.nextInt();
    }
    public void input(){
        System.out.println("input the number of process:");
        for(int i = 0;i<num;i++ ){
            position[i][0] = sc.nextInt();
            position[i][1] = i+1;
        }
    }
    public void adjust(){//调整数组中进程的记录顺序
        for(int i=0;i<num;i++){
            for(int j=1;j<num-i;j++){
                if(position[j-1][0]>position[j][0]){
                    int temp1 = position[j][0];
                    int temp2 = position[j][1];
                    
                    position[j][0] = position[j-1][0];
                    position[j][1] = position[j-1][1];
                    
                    position[j-1][0] = temp1;
                    position[j-1][1] = temp2;
                }
            }
        }
    }
     public void algo(){
         input();
         adjust();
         int init;
         
         for(init = 0;init<num-1;init++){
             if(position[init][0]<initPos && position[init+1][0]>=initPos){
                 break;
             }
         }
         int start = init;
         System.out.println("第一次扫描:");
         for(int i=start;i>=0;i--){       
             System.out.println("第一次扫描:"+"进程"+position[i][1]+"在磁道"+position[i][0]+"完成");     
         }
         
         if(position[init+1][0]!=0){
             System.out.println("磁头已经扫描到磁盘最内层:0");             
         }
         if(position[num-1][0]!=size){
             System.out.println("磁头已经移到磁盘最外层:"+size);
         }
         
         System.out.println("第二次扫描:");
         for(int i=num-1;i>start;i--){             
             System.out.println("第二次扫描:"+"进程"+position[i][1]+"在磁道"+position[i][0]+"完成");
         }
     }   
}

为了直观的感受一下各种算法的差别,我选了大概500个进程处理来比较它们的时间和平均寻道长度(现实中肯定不会有这么多的待处理进程,不然炸了,只是为了比较),通过画折线图的方法进程比较,画折线图的实现过程在前面的文章中已经记录过了,所以直接上结果:

原文地址:http://blog.51cto.com/acevi/2096277

时间: 2024-11-09 02:20:35

磁盘调度算法FCFS、SSTF、SCAN、CSCAN详解的相关文章

FCFS,SSTF,SCAN,FIFO,LRO考点题解

四.应用题 ( 本大题共5 小题,50 分 ) 1. 假设某系统中有五个进程,每个进程的执行时间(单位:ms)和优先数如下表所示(优先数越小,其优先级越高). 进程 执行时间 优先数 P1 P2 P3 P4 P5 10 1 2 1 5 3 1 5 4 2 如果在0时刻,各进程按P1.P2.P3.P4.P5的顺序同时到达,请回答以下问题:(12分) (1)当系统采用先来先服务调度算法时: 进程执行顺序是      p1 p2 p3 p4 p5      平均周转时间是  13.4ms (2)当系统

23、磁盘管理—磁盘阵列(RAID)实例详解

磁盘阵列(RAID)实例详解 raid技术分类 软raid技术 硬raid技术 Raid和lvm的区别 为什么选择用raid RAID详解 RAID-0 RAID-1 RAID-5 Raid-10 Raid的管理 案例:创建一个raid10+冗余盘 磁盘阵列(RAID)实例详解 Raid(磁盘阵列)级别介绍 Raid有"廉价磁盘冗余阵列"的意思,就是利用多块廉价的硬盘组成磁盘组,让数据分部储存在这些硬盘里面,从而达到读取和写入加速的目的:也可以用作数据的冗余,当某块硬盘损毁后,其他硬盘

linux磁盘管理之LVM逻辑卷认识与管理详解(实验详细,可跟做)

Linux磁盘管理之LVM逻辑卷认识与管理详解 前言 本文接着上篇文章作如下延伸:链接:Linux磁盘管理之磁盘管理与文件系统 什么是LVM?为什么需要LVM? 如何具体进行LVM逻辑卷管理? 什么是磁盘配额?为什么需要磁盘配额? 在Linux中进行磁盘配额的条件是什么呢? 如何具体进行磁盘配额? 下面对以上问题逐一讲解,深入实例进行操作,带你深入理解linux磁盘管理之LVM逻辑卷管理. 一.LVM概述 1.什么是LVM?为什么需要LVM? ? 许多 Linux 使用者安装操作系统时都会遇到这

磁盘及文件系统管理详解---急需加强

磁盘管理: 机械式硬盘 U盘.光盘.软盘.硬件.磁带 MBR:Master Boot Record 主引导记录 ln [-s -v] SRC DEST:创建链接文件,默认硬链接 -s:创建软连接 -v:显示过程 硬链接: 1.只能对文件创建,不能应用于目录 2.不能跨文件系统 3.创建硬链接会增加文件被链接的次数 符号链接(软连接): 1.可以应用于目录 2.可以跨文件系统 3.不会增加被链接文件的链接次数 4.其大小为指定的路径所包含的字符个数 du -s -h df:显示整个磁盘分区使用情况

linux下磁盘分区详解

给新硬盘上建立分区时都要遵循以下的顺序:建立主分区→建立扩展分区→建立逻辑分区→激活主分区→格式化所有分区. 一个硬盘的主分区也就是包含操作系统启动所必需的文件和数据的硬盘分区,要在硬盘上安装操作系统,则该硬盘必须得有一个主分区.         扩展分区也就是除主分区外的分区,但它不能直接使用,必须再将它划分为若干个逻辑分区才行.逻辑分区也就是我们平常在操作系统中所看到的D.E.F等盘. 分区从实质上说就是对硬盘的一种格式化.当我们创建分区时,就已经设置好了硬盘的各项物理参数,指定了BIOS系

(转)详解LVS负载均衡之三种工作模型原理和10种调度算法

前言:最近在为我们的产品在做高可用,一边搭环境,一边了解相关知识,搜到这篇博客,质量不错,表述清晰,于是转载过来学习. 标签:详解LVS负载均衡之三种工作模型原理和10种调度算法 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://linuxnx.blog.51cto.com/6676498/1195379 LVS负载均衡原理和算法详解    Internet的快速增长使多媒体网络服务器面对的访问数量快速增加,服务器需要具备提供大

Windows GPT磁盘GUID结构详解

前一篇Windows磁盘MBR结构详解中我们介绍了Basic Disk中的Master Boot Record结构.GPT Disk作为Windows 2003以后引入的分区结构.使用了GUID分区表结构,它与MBR相比好处是支持更大和更多的分区,提高容错.本文介绍了GUID分区表的结构和各个字段的含义. GPT Disk 的Protective MBR: GPT Disk的结构中,第一个LBA位置(LBA 0)存放的是Protective MBR,随后LBA1的位置才是GPT的GUID分区表头

Linux XFS文件系统描述观察及磁盘命令详解

XFS文件系统的描述数据观察 EXT 家族的 dumpe2fs 去观,而XFS 家族用 xfs_info 去观察 [[email protected] ~]# xfs_info挂载点|装置文件名 [[email protected] ~]# df - - T /boot Filesystem      Type     1K-blocks     Used     Available     Use%     Mounted on /dev/vda2        xfs     1038336

linux磁盘分区详解【转】

本文装载自:http://blog.csdn.net/aaronychen/article/details/2270048#comments 在学习 Linux 的过程中,安装 Linux 是每一个初学者的第一个门槛.在这个过程中间,最大的困惑莫过于给硬盘进行分区.虽然,现在各种发行版本的 Linux 已经提供了友好的图形交互界面,但是很多的人还是感觉无从下手.这其中的原因主要是不清楚 Linux 的分区规定,以及它下面最有效的分区工具― Fdisk 的使用方法. 首先我们要对硬盘分区的基本概念