磁盘调度算法实现

  在计算机操作系统中,磁盘调度的算法通常有以下几种:

一、先到先服务算法FCFS( First Come First Serve)

  顾名思意,FCFS算法是按照输入/输出的先后次序为各个进程服务,即依请求次序访问磁道。

  请求次序:1  2  3  4  5  6

  访问磁道:34   33 98     76     2      88

  如上所示,FCFS依次访问磁道34,33,98,76,2,88,总移动磁道数为:1+65+22+74+86=248.

  此算法易于实现,但效率低下,适合于负载很轻的系统。

  FCFS代码实现如下:

FCFS算法

#include
<stdio.h>
#include
<stdlib.h>
#include
<time.h>
#include
<math.h>

#define DISKMAX 1000
#define DISKTOTAL 1000
#define OK 1
#define ERROR -1

/*先到先服务磁盘调度*/
void FCFS(int *R,int present_disk,int request_num){
int i;
int count=0; //磁头移动总次数
int step; //访问下一个磁道磁头移动次数

printf(
"\nMoving Order Moving Path Moving Steps");

step
=abs(present_disk-R[0]); /*绝对值*/
count
+=step;
printf(
"\n 1 %d---->%d %d",present_disk,R[0], step);/*输出访问轨迹*/


for(i=0;i<request_num-1;i++){ /*遍历数组*/
step
=abs(R[i]-R[i+1]);
count
+=step;
printf(
"\n %d %d---->%d %d",i+2,R[i],R[i+1], step);
}

printf(
"\nTotal moving steps:%d",count); /*输出磁头总移动次数*/
printf(
"\nAverage moving steps:%d",count/request_num); /*平均移动次数*/
}

 

 

运行结果如下:

 

input number of base disk(1~1000):100
The base disk is:
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 5
6 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
input number of request disk(1~1000)6
System creates stochastic numbers for request disk :
 22 17 27 9 8 78
input present disk number(0~99):2
/*********************************/


input number of base disk(1~1000):100 (模拟产生多少个磁道)
The base disk is: 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 

79 80 81 8283 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

input number of request disk(1~1000):(模拟产生多少个请求)

6
System creates stochastic numbers for request disk :

 22 17 27 9 8 78

input present disk number(0~99):2 (当前磁头在哪个磁道)

 

 

(输出结果)

Moving Order    Moving  Path    Moving Steps

  1              2---->22            20

  2             22---->17            5

  3             17---->27            10

  4             27---->9            18

  5             9---->8            1

  6             8---->78            70

Total moving steps:124

Average moving steps:20


二、最短寻道时间优先算法SSTE(Shortest Seek Time First)

  SSTE基于这样的思想:磁头总是访问距离当前磁道最近的磁道。

  请求次序:1  2  3  4  5  6

  访问磁道:34   33 98     76     2      88

  如上所示,SSTE依次访问磁道34,33,2,76,88,98,总移动磁道数为:1+31+74+12+10=128,比FCFS的248道访问总数少了很多。

  SSTE的实现代码如下:

SSTF算法
/*最短寻道时间优先算法*/
void SSTF(int *R,int present_disk,int request_num){
int i=0;
int temp,key;
int count=0,step=0;
int up=0,down=0;
int up_step=0,down_step=0;

key
=SearchPresent(R,request_num , present_disk); /*查找当前磁道*/
printf(
"\nMoving Order Moving Path Moving Steps");


while(key!=0&&key!=request_num){ /*磁道未到头或尾*/
i
++;
if((R[key]-R[key-1-down])<(R[key+1+up]-R[key])){ /*左边的磁道比右边的磁道近*/
temp
=key-1-down; /*记录下一个磁道*/
down_step
++;
down
=0;
up
=down_step+up_step;
}
else { /*右边的磁道比左边的磁道近*/
temp
=key+1+up; /*记录下一个磁道*/
up_step
++;
up
=0;
down
=up_step+down_step;
}
step
=abs(R[key]-R[temp]);
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[temp], step);
key
=temp;
}



if(key==0){ /*当前磁头在头*/
i
++;
temp
=key+1+up; /*记录下一个将要访问的磁道*/
step
=abs(R[key]-R[temp]);
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[temp], step);

key
=temp;
while(key!=request_num){
i
++;
step
=R[key+1]-R[key];
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[key+1], step);
key
++;
}
}
else{ /*当前磁头在尾*/
i
++;
temp
=key-1-down; /*记录下一个将要访问的磁道*/
step
=abs(R[key]-R[temp]);
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[temp], step);


key
=temp;
while(key!=0){
i
++;
step
=R[key]-R[key-1];
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[key-1], step);
key
--;
}
}
printf(
"\nTotal moving steps:%d",count);
printf(
"\nAverage moving steps:%d",count/request_num);
}

 

  运行结果如下:

 Moving Order    Moving  Path    Moving Steps

  1             2---->8            6

  2             8---->9            1

  3             9---->17            8

  4             17---->22            5

  5             22---->27            5

  6             27---->78            51

Total moving steps:76

Average moving steps:12

 

三、电梯算法(扫描算法)Scan

  电梯算法其基本思想与电梯工作原理类似:最开始的时候,磁头向访问请求的方向A扫描,在磁头移动过程中,如果经过的磁道有访问请求,则为其服务。接着判断A方向是否仍有请求,有则向A移动处理,否则调转方向向B移动:

 

   其代码实现如下:

 

SCAN算法
/*电梯扫描算法*/
void SCAN(int *R,int present_disk,int request_num){
int i=0;
int temp,key;
int count=0,step=0;
key
=SearchPresent(R,request_num , present_disk); /*查找当前磁道*/
temp
=key;
if(key==request_num){ /*当前磁头在磁道头*/
while(key!=0){ /*向内移动*/
step
=R[key]-R[key-1];
count
+=step;
printf(
"\n %d %d---->%d %d",i+1,R[key],R[key-1], step);
key
--;
i
++;
}
}
else if(key==0){ /*当前磁头在磁道尾*/
while(key!=request_num){
step
=R[key+1]-R[key];
count
+=step;
printf(
"\n %d %d---->%d %d",i+1,R[key],R[key+1], step);
key
++;
i
++;
}
}
else{ /*当前磁头不在头或尾*/
while(key!=0){ /*向内移动*/
step
=R[key]-R[key-1];
count
+=step;
printf(
"\n %d %d---->%d %d",i+1,R[key],R[key-1], step);
key
--;
i
++;
}
/*向外移动*/
i
++;
step
=R[temp+1]-R[key];
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[temp+1], step);
key
=temp+1;
while(key!=request_num){
step
=R[key+1]-R[key];
count
+=step;
printf(
"\n %d %d---->%d %d",i+1,R[key],R[key+1], step);
key
++;
i
++;
}
}

printf(
"\nTotal moving steps:%d",count);
printf(
"\nAverage moving steps:%d",count/request_num);
}

 

 

 

 运行结果如下:

 

 

Moving Order    Moving  Path    Moving Steps

  1             2---->8            6

  2             8---->9            1

  3             9---->17            8

  4             17---->22            5

  5             22---->27            5

  6             27---->78            51

Total moving steps:76

Average moving steps:12


四、总结

  以上用代码实现了磁盘调度的一些算法,并简单地分析了算法的基本思想。

  完整代码如下:

 

磁盘调度完整代码
#include<stdio.h>
#include
<stdlib.h>
#include
<time.h>
#include
<math.h>

#define DISKMAX 1000
#define DISKTOTAL 1000
#define OK 1
#define ERROR -1

int cmp ( const void *a , const void *b ) /**/
{
return *(int *)a - *(int *)b;
}

void SetBaseDisk(int *base_num){/*设置磁盘磁道数*/
int i;
printf(
"\ninput number of base disk(1~%d):",DISKMAX);
scanf(
"%d",base_num);
if(*base_num<=0||*base_num>DISKMAX){printf("ERROR!");exit(0);}
printf(
"\nThe base disk is:\n");
for(i=0;i<*base_num;i++){
printf(
" %d",i);
}
}



void SetRequestDisk(int *R,int *request_num,int base_num){/*设置请求访问磁道数*/
int i;
srand(time(NULL));
printf(
"\ninput number of request disk(1~%d)",DISKTOTAL);
scanf(
"%d",request_num);
if(*request_num<=0||*request_num>DISKTOTAL){printf("ERROR!");exit(0);}
printf(
"\nSystem creates stochastic numbers for request disk :\n");
for(i=0;i<*request_num;i++){
R[i]
=rand()%(base_num-1);//生成随机数
printf(" %d",R[i]);
}
}


void SetPresentDisk(int *present_disk,int *base_num){/*设置当前磁道*/
printf(
"\ninput present disk number(0~%d):",*base_num-1);
scanf(
"%d",present_disk);
if(*present_disk<0||*present_disk>=*base_num){printf("ERROR!");exit(0);}
}


/*先到先服务磁盘调度*/
void FCFS(int *R,int present_disk,int request_num){
int i;
int count=0; //磁头移动总次数
int step; //访问下一个磁道磁头移动次数

printf(
"\nMoving Order Moving Path Moving Steps");

step
=abs(present_disk-R[0]); /*绝对值*/
count
+=step;
printf(
"\n 1 %d---->%d %d",present_disk,R[0], step);/*输出访问轨迹*/


for(i=0;i<request_num-1;i++){ /*遍历数组*/
step
=abs(R[i]-R[i+1]);
count
+=step;
printf(
"\n %d %d---->%d %d",i+2,R[i],R[i+1], step);
}

printf(
"\nTotal moving steps:%d",count); /*输出磁头总移动次数*/
printf(
"\nAverage moving steps:%d",count/request_num); /*平均移动次数*/
}




int Sort(int *R,int request_num,int present_disk){/*调用库函数的快速排序函数*/
R[request_num]
=present_disk;//加入当前磁道
qsort(R,request_num+1,sizeof(R[0]),cmp);
return 1;
}


int SearchPresent(int *R,int request_num ,int present_disk){/*二分查找法,寻找当前磁道*/
int left,right,middle;
left
=0;
right
=request_num;
while(left<=right){
middle
=(left+right)/2;
if(present_disk==R[middle])return middle;
if(present_disk>R[middle])left=middle+1;
else right=middle-1;
}
return -1;
}



/*最短寻道时间优先算法*/
void SSTF(int *R,int present_disk,int request_num){
int i=0;
int temp,key;
int count=0,step=0;
int up=0,down=0;
int up_step=0,down_step=0;

key
=SearchPresent(R,request_num , present_disk); /*查找当前磁道*/
printf(
"\nMoving Order Moving Path Moving Steps");


while(key!=0&&key!=request_num){ /*磁道未到头或尾*/
i
++;
if((R[key]-R[key-1-down])<(R[key+1+up]-R[key])){ /*左边的磁道比右边的磁道近*/
temp
=key-1-down; /*记录下一个磁道*/
down_step
++;
down
=0;
up
=down_step+up_step;
}
else { /*右边的磁道比左边的磁道近*/
temp
=key+1+up; /*记录下一个磁道*/
up_step
++;
up
=0;
down
=up_step+down_step;
}
step
=abs(R[key]-R[temp]);
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[temp], step);
key
=temp;
}



if(key==0){ /*当前磁头在头*/
i
++;
temp
=key+1+up; /*记录下一个将要访问的磁道*/
step
=abs(R[key]-R[temp]);
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[temp], step);

key
=temp;
while(key!=request_num){
i
++;
step
=R[key+1]-R[key];
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[key+1], step);
key
++;
}
}
else{ /*当前磁头在尾*/
i
++;
temp
=key-1-down; /*记录下一个将要访问的磁道*/
step
=abs(R[key]-R[temp]);
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[temp], step);


key
=temp;
while(key!=0){
i
++;
step
=R[key]-R[key-1];
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[key-1], step);
key
--;
}
}
printf(
"\nTotal moving steps:%d",count);
printf(
"\nAverage moving steps:%d",count/request_num);
}

/*电梯扫描算法*/
void SCAN(int *R,int present_disk,int request_num){
int i=0;
int temp,key;
int count=0,step=0;
key
=SearchPresent(R,request_num , present_disk); /*查找当前磁道*/
temp
=key;
if(key==request_num){ /*当前磁头在磁道头*/
while(key!=0){ /*向内移动*/
step
=R[key]-R[key-1];
count
+=step;
printf(
"\n %d %d---->%d %d",i+1,R[key],R[key-1], step);
key
--;
i
++;
}
}
else if(key==0){ /*当前磁头在磁道尾*/
while(key!=request_num){
step
=R[key+1]-R[key];
count
+=step;
printf(
"\n %d %d---->%d %d",i+1,R[key],R[key+1], step);
key
++;
i
++;
}
}
else{ /*当前磁头不在头或尾*/
while(key!=0){ /*向内移动*/
step
=R[key]-R[key-1];
count
+=step;
printf(
"\n %d %d---->%d %d",i+1,R[key],R[key-1], step);
key
--;
i
++;
}
/*向外移动*/
i
++;
step
=R[temp+1]-R[key];
count
+=step;
printf(
"\n %d %d---->%d %d",i,R[key],R[temp+1], step);
key
=temp+1;
while(key!=request_num){
step
=R[key+1]-R[key];
count
+=step;
printf(
"\n %d %d---->%d %d",i+1,R[key],R[key+1], step);
key
++;
i
++;
}
}

printf(
"\nTotal moving steps:%d",count);
printf(
"\nAverage moving steps:%d",count/request_num);
}


int main(){
int R[DISKTOTAL];
int base_num,request_num,present_disk;
int choose;
int flag=0;

SetBaseDisk(
&base_num);
SetRequestDisk(R,
&request_num,base_num);
SetPresentDisk(
&present_disk,&base_num);


do{
printf(
"\n/*********************************/");
printf(
"\n\n1.先到先服务FCFS磁盘调度算法");
printf(
"\n\n2.最短寻道时间优先SSTF磁盘调度算法");
printf(
"\n\n3.电梯扫描算法SCAN磁盘调度算法");
printf(
"\n\n4.退出.");
printf(
"\n\n/*******************************/");
printf(
"\n\n请输入您的选择:(1 , 2 , 3 ,4 )");
scanf(
"%d",&choose);//输入选择


switch(choose){
case 1:{
FCFS(R,present_disk,request_num);
}
break;
case 2:{
if(flag==0)flag=Sort(R,request_num,present_disk); //排序
SSTF(R,present_disk,request_num);
}
break;
case 3:{
if(flag==0)flag=Sort(R,request_num,present_disk); //排序
SCAN(R,present_disk,request_num);
}
break;

}
/*switch*/

}
while(choose>=1&&choose<4);
printf(
"\n再见!");
return 0;
}

 

 

 

posted @ 2010-04-27 18:13  达闻东  阅读(3659)  评论(0编辑  收藏  举报