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

本文详细介绍了四种常见的磁盘调度算法:FCFS(先来先服务)、SSTF(最短寻道时间)、SCAN(扫描)和CSCAN(循环扫描)。每种算法的原理、优缺点以及Java实现进行了阐述,包括如何处理进程和服务顺序,以及如何减少平均寻道长度。最后,通过模拟大量进程对比了这些算法的性能差异。
摘要由CSDN通过智能技术生成

常见的磁盘调度算法有:

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

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

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

position1[i][0] = position[i][0];

position1[i][1] = i+1;

}

//寻找磁头访问的序列

for(int i=0;i

for(int j=0;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

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

position1[i] = sc.nextInt(); //记录进程所在的磁道号

}

}

public void adjust(){

//按照磁道编号将进程排序,就是一个冒泡排序

for(int i=0;i

for(int j=1;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

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

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

position[i][0] = sc.nextInt();

position[i][1] = i+1;

}

}

public void adjust(){//调整数组中进程的记录顺序

for(int i=0;i

for(int j=1;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

if(position[init][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个进程处理来比较它们的时间和平均寻道长度(现实中肯定不会有这么多的待处理进程,不然炸了,只是为了比较),通过画折线图的方法进程比较,画折线图的实现过程在前面的文章中已经记录过了,所以直接上结果:

c76c54e89157671f6bfab4a5c8670ea9.png

a3b783666bfae9463f241f4647b836e4.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值