设计五:磁盘调度管理
设计目的:
加深对请求磁盘调度管理实现原理的理解,掌握磁盘调度算法。
设计内容:
通过编程实现不同磁盘调度算法。
设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。选择磁盘调度算法,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。
常用的磁盘调度算法简介如下,请在以下算法中任意选择两种实现,并对算法性能进行分析对比。
1. 最短寻道优先算法SSTF:该算法选择这样的进程:其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。
2. 扫描算法SCAN:该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。
3.循环扫描算法CSCAN:CSCAN算法规定磁头单向移动,例如,只是自里向外移动,当磁头移到最外的磁道并访问后,磁头立即返回到最里的欲访问的磁道,亦即将最小磁道号紧接着最大磁道号构成循环,进行循环扫描。
代码如下:
import java.util.Scanner; import java.util.Arrays; import java.util.Random; class Cipandiaodu{ public static void main(String[] args){ /* 要用到的几种算法分别是 最短寻道时间优先调度算法 循环扫描调度算法 */ Scanner reader=new Scanner(System.in); System.out.println("请输入算法:1、最短寻道时间优先调度算法 2、循环扫描调度算法"); int input=reader.nextInt(); switch(input){ case 1: SSTF hhh = new SSTF(); hhh.way(); break; case 2: CSCAN hh = new CSCAN(); hh.way(); break; default: System.out.println("非法输入"); break; } } } class SSTF{ void way(){ int k=1; int now,l,r; int i,j,sum=0; float ave; int num; Scanner input = new Scanner(System.in); System.out.println("请输入磁道数:"); num = input.nextInt(); int[] cidao=new int[num]; Random rand = new Random(); for(i = 0; i < num; i++) { cidao[i] = rand.nextInt(200) + 1 ; } System.out.print("磁道序列为:"); for(i = 0; i < num; i++) { System.out.print(cidao[i]+" "); } System.out.println(); Arrays.sort(cidao); System.out.print("请输入当前的磁道号:"); Scanner w=new Scanner(System.in); now = w.nextInt(); if(cidao[num-1]<=now) //若当前磁道号大于请求序列中最大者,则直接由外向内依次给予各请求服务 { System.out.println("磁盘扫描序列为:"); for(i=num-1;i>=0;i--) System.out.print(cidao[i]+" "); sum=now-cidao[0]; } if(cidao[0]>=now) //若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务 { System.out.println("磁盘扫描序列为:"); for(i=0;i<num;i++) System.out.print(cidao[i]+" "); sum=cidao[num-1]-now; } if(now>cidao[0]&&now<cidao[num-1]) //若当前磁道号大于请求序列中最小者且小于最大者 { System.out.println("磁盘扫描序列为:"); while(cidao[k]<now) //确定当前磁道在已排的序列中的位置 { k++; } l=k-1; r=k; while((l>=0)&&(r<num)) //当前磁道在请求序列范围内 { if((now-cidao[l])<=(cidao[r]-now)) //选择与当前磁道最近的请求给予服务 { System.out.print(cidao[l]+" "); sum+=now-cidao[l]; now=cidao[l]; l=l-1; } else { System.out.print(cidao[r]+" "); sum+=cidao[r]-now; now=cidao[r]; r=r+1; } } if(l==-1) //磁头移动到序列的最小号,返回外侧扫描仍未扫描的磁道 { for(j=r;j<num;j++) { System.out.print(cidao[j]+" "); } sum+=cidao[num-1]-cidao[0]; } else //磁头移动到序列的最大号,返回内侧扫描仍未扫描的磁道 { for(j=l;j>=0;j--) { System.out.print(cidao[j]+" "); } sum+=cidao[num-1]-cidao[0]; } } ave=(float)(sum)/(float)(num); System.out.println(); System.out.println("平均寻道长度: "+ave); } } class CSCAN{ void way(){ int k=1; int now,l,r; int i,j,sum=0; int a; float ave; int num; Scanner input = new Scanner(System.in); System.out.println("请输入磁道数:"); num = input.nextInt(); int[] cidao=new int[num]; Random rand = new Random(); for(i = 0; i < num; i++) { cidao[i] = rand.nextInt(200) + 1 ; } System.out.print("磁道序列为:"); for(i = 0; i < num; i++) { System.out.print(cidao[i]+" "); } System.out.println(); Arrays.sort(cidao); System.out.print("请输入当前的磁道号:"); Scanner w=new Scanner(System.in); now=w.nextInt(); if(cidao[num-1]<=now) //若当前磁道号大于请求序列中最大者,则直接将移动臂移动到最小号磁道依次向外给予各请求服务 { System.out.println("磁盘扫描序列为:"); for(i=0;i<num;i++) System.out.print(cidao[i]+" "); sum = now-2*cidao[0]+cidao[num-1]; } if(cidao[0]>=now) //若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务,此情况同最短寻道优先 { System.out.println("磁盘扫描序列为:"); for(i=0;i<num;i++) System.out.print(cidao[i]+" "); sum=cidao[num-1]-now; } if(now>cidao[0]&&now<cidao[num-1]) //若当前磁道号大于请求序列中最小者且小于最大者 { System.out.println("磁盘扫描序列为:"); while(cidao[k]<now) //单向反复地从内向外扫描 { k++; } l=k-1; r=k; for(j=r;j<num;j++) { System.out.print(cidao[j]+" "); } for(j=0;j<r;j++) //当扫描完最大号磁道,磁头直接移动到最小号磁道,再向外扫描未扫描的磁道 { System.out.print(cidao[j]+" "); } sum=2*cidao[num-1]+cidao[l]-now-2*cidao[0]; } ave=(float)(sum)/(float)(num); System.out.println(); System.out.println("平均寻道长度: "+ave); } }