一、设计目的:
加深对请求磁盘调度管理实现原理的理解,掌握磁盘调度算法中的扫描寻道算法。
二、设计内容
通过编程实现磁盘调度中扫描寻道算法。设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。选择磁盘调度算法,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。
扫描算法SCAN:该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。
三、程序结构:
首先,用srand()和rand()函数分别进行初始化、随机数定义和产生互不相同的磁道号序列;接着,对所有磁道序列降序排序;
然后,找到访问的第一个磁道,必一一访问所有的磁道;
最后,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。
源程序:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 51
struct TCB //track control block
{
int tn; //track number磁道号
int flag; //完成标志 flag=-1没完成 flag=1完成
}track[N];
int randomnumber(int n,int max,int min) //各磁道互不相同
{
srand((int)time(NULL));
int t; //用来判断这个随机数是否重复
int x,y;
for(x=1;x<=n;)
{
t=rand()%(max-min+1)+min;
for(y=1;y<x;y++)
{if(track[y].tn==t) break;}
if(y==x) //不重复
{track[x++].tn=t;track[--x].flag=-1;x++;}//有进程的为-1,没有的为0 (系统初始化)
}
}
int SCAN(int n,int present,int max,int min,int option)
{
int i,j;
int z=1;
int start; //存放磁头访问开始位置
int sum=0; //磁头移动总数
for(i=1;i<n;i++) //对磁道从小到大排序
for(j=i+1;j<=n;j++)
if(track[i].tn>track[j].tn)
{
track[0].tn=track[i].tn;
track[i].tn=track[j].tn;
track[j].tn=track[0].tn;
}
if(present<=track[1].tn) start=1; //找分断点和访问开始位置
else if(present>=track[n].tn) start=n;
else
{
for(i=2;i<n;i++)
if(track[i-1].tn<present&&track[i+1].tn>present)
{start=i;break;}
if(track[start].tn==present) start=i;
else if(track[start].tn<=present)
{
if(option==1) start=i+1;
else if(option==0) start=i;
}
else if(track[start].tn>=present)
{
if(option==1) start=i;
else if(option==0) start=i-1;
}
}
//找到磁头访问开始位置后,就是扫描访问各磁道
printf("\n\n\n磁道访问顺序:");
if(start==1||start==n)
{
if(start==1)
for(j=1;j<=n;j++)
{printf("%d ",track[j].tn); sum+=abs(present-track[j].tn); present=track[j].tn;}
else if(start==n)
for(j=n;j>=1;j--)
{printf("%d ",track[j].tn);sum+=abs(present-track[j].tn);present=track[j].tn;}
}
else
{
if(option==1) //自低向高走
{
for(j=start;j<=n;j++) {printf("%d ",track[j].tn);sum+=abs(present-track[j].tn);present=track[j].tn;}
for(j=start-1;j>=1;j--) {printf("%d ",track[j].tn);sum+=abs(present-track[j].tn);present=track[j].tn;}
}
else if(option==2) //自高向低走
{
for(j=start;j>=1;j--){printf("%d ",track[j].tn);sum+=abs(present-track[j].tn);present=track[j].tn;}
for(j=start+1;j<=n;j++){printf("%d ",track[j].tn);sum+=abs(present-track[j].tn);present=track[j].tn;}
}
printf("\n\n磁道移动总数sum=%d\n",sum);
printf("平均寻道总数=%lf\n",sum/(float)n);
}
}
int main()
{
int n;
int max,min,current;
int option; //用于磁头移动方向选择
printf("\t\t最短寻道时间优先\n\n");
printf("请输入请求进程的个数(1-50):");
scanf("%d",&n);
printf("请输入最小磁道号:");
scanf("%d",&min);
printf("请输入最大磁道号:");
scanf("%d",&max);
printf("请输入当前磁头所在的位置:");
scanf("%d",¤t);
printf("\n请选择磁头的移动方向: 1.自低向高; 2.自高向低。\n");
scanf("%d",&option);
randomnumber(n,max,min);
//for(int i=1;i<=N;i++) //检验产生的数是否符合要求
//printf("%d %d\n",track[i].tn,track[i].flag);
printf("\n磁道请求调度先后顺序为:\n");
for(int j=1;j<=n;j++)
printf("%d\t",track[j].tn);
SCAN(n,current,max,min,option);
return 0;
}