实验三 磁盘调度算法设计
实验目的:
通过对磁盘调度算法的设计,深入理解提高磁盘访问速度的原理。
实验内容:
模拟实现磁盘调度算法:最短寻道时间优先(SSTF)和扫描(SCAN)算法。
实验步骤:
理解各调度算法的工作原理
对给出的任意的磁盘请求序列、计算平均寻道长度;要求可定制磁盘请求序列长度、磁头起始位置、磁头移动方向。
测试:假设磁盘访问序列:98,183,37,122,14,124,65,67;读写头起始位置:53,方向:磁道增加的方向。输入此类数据后,程序按照选定的算法,自动给出访问序列,并且算出经过的磁道总数。
下面是具体的实验过程:
1.寻道时间优先(SSTF)算法
(1)寻道时间优先算法是要求被访问的磁道与当前磁头所在磁道距离最短,使得每次的寻道时间最短,但是不能保证最短的平均寻道时间。
2.扫描(SCAN)算法
(1)SCAN扫描算法不仅考虑欲访问的磁道与当前磁道之间的距离还优先考虑了当前磁道移动的方向。可以防止“饥饿”现象的发生。图2所示的为SCAN算法的流程图。
3.SSTF和SCAN算法代码
(1)代码目录结构图如图3所示。从上到小为SCAN算法实现,SSTF算法实现以及两个算法的测试类。
图3 代码结构目录图
(2)SSTF算法代码如下。主要的功能有SSTF算法的实现和磁道访问序列、磁道访问数、平均磁道访问数格式化输出。
public class SSTF {
private int visit[];
private int nearIndex=0;
public int[] sstf(int queue[],int start){
int nearNum=9999;
visit=new int[queue.length];
for(int i=0;i<queue.length;i++){
for(int j=0;j<queue.length;j++){
if(queue[j]!=-1){
if(Math.abs(nearNum-start)>Math.abs(queue[j]-start)){
nearNum=queue[j];
nearIndex=j;
}
}
}
visit[i]=nearNum;
queue[nearIndex]=-1;
start=nearNum;
nearNum=9999;
}
return visit;
}
public void print(int visit[],int start){
double sum=0;
System.out.print("访问序列:");
for(int i=0;i<visit.length;i++){
System.out.print(visit[i]+" ");
sum=Math.abs(visit[i]-start)+sum;
start=visit[i];
}
System.out.println();
System.out.println("经过的磁道总数:"+sum);
System.out.println("平均寻道长度:"+sum/visit.length);
}
}
(3)SCAN算法代码如下。主要的功能有SCAN算法的实现和磁道访问序列、磁道访问数、平均磁道访问数格式化输出。
public class SCAN{
private int visit[];
private int nearIndex=0;
int nearNum=9999;
public int[] scan(int queue[],int start,int direction){
int index=0;
visit=new int[queue.length];
for(int i=0;i<queue.length;i++){
index=-1;
for(int j=0;j<queue.length;j++){
if(queue[j]!=-1){
if((direction==1)&&(queue[j]>start)&&(Math.abs(nearNum-start)>Math.abs(queue[j]-start))){
nearNum=queue[j];
nearIndex=j;
index=0;
}
else if((direction==0)&&(queue[j]<start)&&(Math.abs(nearNum-start)>Math.abs(queue[j]-start))){
nearNum=queue[j];
nearIndex=j;
index=0;
}
}
}
if((direction==1)&&(index==-1)){
direction=0;
i=i-1;
}
else if((direction==0)&&(index==-1)){
direction=1;
i=i-1;
}
if(index==0){
visit[i]=nearNum;
queue[nearIndex]=-1;
start=nearNum;
nearNum=9999;
}
}
return visit;
}
public void print(int visit[],int start){
double sum=0;
System.out.print("访问序列:");
for(int i=0;i<visit.length;i++){
System.out.print(visit[i]+" ");
sum=Math.abs(visit[i]-start)+sum;
start=visit[i];
}
System.out.println();
System.out.println("经过的磁道总数:"+sum);
System.out.println("平均寻道长度:"+sum/visit.length);
}
}
(4)测试类代码如下。主要完成的功能有磁盘调度算法的选择,磁盘请求序列长度的定义,磁盘请求访问序列的输入,起始位置的输入,调用对应的算法输入磁盘访问序列和磁道总数以及平均寻道长度。
//测试的序列98 183 37 122 14 124 65 67
public class Test {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
boolean f=true;
int[] queue=null;//磁盘访问序列
int start=0;//当前磁头所在的位置
while(f) {
System.out.println("输入要执行的磁盘调度算法\n"
+ "1---代表SSTF算法\n"
+ "2---代表SCAN算法\n"
+ "3---代表退出系统");
String flag=sc.next();
switch(flag) {
case "1":
System.out.println("请输入磁盘请求序列长度:");
int count=sc.nextInt();
queue=new int[count];//访问序列
System.out.println("请输入磁盘请求访问序列:");
for(int i=0;i<count;i++){
queue[i]=sc.nextInt();//初始化访问序列
}
SSTF sstf=new SSTF();
System.out.println("请输入读写头起始位置:");
start=sc.nextInt();
sstf.print(sstf.sstf(queue, start),start);
System.out.println("*******************分割线*******************");
break;
case "2":
System.out.println("请输入磁盘请求序列长度:");
int length=sc.nextInt();//length请求队列长度
System.out.println("请输入磁盘请求访问序列:");
queue=new int[length];//queue磁盘访问队列的长度
for(int i=0;i<length;i++){
queue[i]=sc.nextInt();//初始化此磁盘队列
}
SCAN scan=new SCAN();//创建SCAN对象
System.out.println("请输入读写头起始位置:");
start=sc.nextInt();//strat为读写磁头所在的位置
System.out.println("磁道增加的方向:(0向磁道号减少的方向移动,1向磁道号增加的方向移动)");
int direction=sc.nextInt();//输入方向
scan.print(scan.scan(queue, start,direction),start);//打印磁道访问序列,磁道数和平均访问的次数
System.out.println("*******************分割线*******************");
break;
case "3":
f=false;//退出
System.out.println("欢迎您的下次使用!");
System.out.println("*******************分割线*******************");
break;
default:
f=false;
System.out.println("对不起,您的输入有误,欢迎您的下次使用!");
System.out.println("*******************分割线*******************");
break;
}
}
}
}
运行,经过验证可知结果正确。