磁盘调度算法实现

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

一、先到先服务算法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代码实现如下:

ContractedBlock.gif ExpandedBlockStart.gif 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的实现代码如下:

ContractedBlock.gif ExpandedBlockStart.gif 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移动:

 

2010042718432581.jpg

   其代码实现如下:

 

ContractedBlock.gif ExpandedBlockStart.gif 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


四、总结

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

  完整代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif 磁盘调度完整代码
 
   
#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 ;
}

 

 

 

转载于:https://www.cnblogs.com/xnwyd/archive/2010/04/27/1722296.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值