1、实验目的
(1) 了解磁盘结构以及磁盘上数据的组织方式。
(2) 掌握磁盘访问时间的计算方式。
(3) 掌握常用磁盘调度算法及其相关特性。
2、实验内容
本实验通过编程模拟实现几种常见的磁盘调度算法。
(1)测试数据:从磁道100号开始,按照磁道调度程序的接收顺序分别为55、58、39、18、90、160、150、38、184
(2)使用 C 语言编程实现 FIFO、SSTF、SCAN、C-SCAN 算法。
3、代码
#include<stdio.h>
#include<math.h>
void FIFO(int start,int s[9]){ //先进先出
int i;
double count1=0;
int s1[9];
for(i=0;i<9;i++){
s1[i]=s[i];
if(s[i]<start)
count1=count1+start-s[i]; //应该看绝对值,距离最近的时候可能下一个被访问的磁道小于当前磁道,也有可能下一个被访问的磁道大于当前磁道
else
count1=count1+s[i]-start;
start=s[i];
}
for(i=0;i<9;i++){
if(i==8)
printf("%d\n",s1[i]);
else
printf("%d,",s1[i]);
}
printf("平均寻道长度为:");
printf("%.1f\n",count1/9);
}
void SSTF(int start,int s[9],int big[9],int small[9],int a,int b){ //最短服务时间优先
int i,j,temp;
double count2=0;
int s2[9];
if(abs(start-big[0])>abs(start-small[b-1])){ //比较距离,得到最短时间优先序列
for(i=0;i<9;i++){
if(i<b)
s2[i]=small[b-i-1];
else
s2[i]=big[i-b];
}
}
else{
for(i=0;i<9;i++){
if(i<a)
s2[i]=big[i];
else
s2[i]=small[b-1-(i-a)];
}
}
for(i=0;i<9;i++){
if(s2[i]<start)
count2=count2+start-s2[i]; //应该看绝对值,距离最近的时候可能下一个被访问的磁道小于当前磁道,也有可能下一个被访问的磁道大于当前磁道
else
count2=count2+s2[i]-start;
start=s2[i];
}
for(i=0;i<9;i++){
if(i==8)
printf("%d\n",s2[i]);
else
printf("%d,",s2[i]);
}
printf("平均寻道长度为:");
printf("%.1f\n",count2/9);
}
void sort(int sort[9],int length){ //对磁道顺序进行排序,比初始磁道号大的按从小到大的顺序放在big数组中,比初始磁道号小的按从小到大的顺序放在small数组中
int i,j,temp;
for(i=0;i<length;i++){
for(j=i+1;j<length;j++){
if(sort[i]>sort[j]){
temp=sort[i];
sort[i]=sort[j];
sort[j]=temp;
}
}
}
}
void SCAN(int start,int s[9],int big[9],int small[9],int a,int b){ //电梯算法
char ch;
int s3[9];
int i,j;
double count3=0;
printf("请选择是按磁道号减小的顺序,还是按磁道号增大的顺序('b'增大,‘s'减小):");
scanf("%c",&ch);
getchar(); //必须得加getchar(),因为回车也是一个字符,不加getchar()if语句不能进入
if(ch=='b'){
for(i=0;i<9;i++){
if(i<a){
s3[i]=big[i];
}
else
s3[i]=small[b-1-(i-a)]; //到达扫描方向的最后一个磁道,反转方向扫描
}
}
else{
for(i=0;i<9;i++){
if(i<b)
s3[i]=small[b-1-i];
else
s3[i]=big[i-b]; //到达扫描方向的最后一个磁道,反转方向扫描
}
}
for(i=0;i<9;i++){
if(s3[i]<start)
count3=count3+start-s3[i];
else
count3=count3+s3[i]-start;
start=s3[i];
}
for(i=0;i<9;i++){
if(i==8)
printf("%d\n",s3[i]);
else
printf("%d,",s3[i]);
}
printf("平均寻道长度为:");
printf("%.1f\n",count3/9);
}
void CSCAN(int start,int s[9],int big[9],int small[9],int a,int b){ //循环扫描算法
char ch;
int s4[9];
int i,j;
double count4=0;
printf("请选择是按磁道号减小的顺序,还是按磁道号增大的顺序('b'增大,‘s'减小):");
scanf("%c",&ch);
getchar();
if(ch=='b'){
for(i=0;i<9;i++){
if(i<a){
s4[i]=big[i];
}
else
s4[i]=small[i-a]; //到达扫描方向的最后一个磁道,返回到磁盘相反方向末端
}
}
else{
for(i=0;i<9;i++){
if(i<b)
s4[i]=small[b-1-i];
else
s4[i]=big[a-1-(i-b)]; 到达扫描方向的最后一个磁道,返回到磁盘相反方向末端
}
}
for(i=0;i<9;i++){
if(s4[i]<start)
count4=count4+start-s4[i];
else
count4=count4+s4[i]-start;
start=s4[i];
}
for(i=0;i<9;i++){ //输出磁盘访问顺序
if(i==8)
printf("%d\n",s4[i]);
else
printf("%d,",s4[i]);
}
printf("平均寻道长度为:"); //计算平均寻道长度
printf("%.1f\n",count4/9);
}
int main(void){
int start=100;//从磁道100处开始
int s[9]={55,58,39,18,90,160,150,38,184}; //被请求的磁道顺序
int a=0,b=0,i;
int big[9],small[9];
for(i=0;i<9;i++){
if(s[i]>start){
big[a++]=s[i];
}
else{
small[b++]=s[i];
}
}
sort(big,a); //进行排序确保每次都能选择从当前位置开始移动最少的磁盘号
sort(small,b);
FIFO(start,s);
SSTF(start,s,big,small,a,b);
SCAN(start,s,big,small,a,b);
CSCAN(start,s,big,small,a,b);
}
4、运行截图