磁盘调度算法
算法描述:
(1)最短寻道时间调度算法:SSTF算法选择调度处理的磁道是与当前磁头所在磁道距离最近的磁道,以使每次的寻找时间最短。当然,总是选择最小寻找时间并不能保证平均寻找时间最小,但是能提供比FCFS算法更好的性能。这种算法会产生“饥饿”现象。
(2)扫描算法:SCAN算法在磁头当前移动方向上选择与当前磁头所在磁道距离最近的请求作为下一次服务的对象。由于磁头移动规律与电梯运行相似,故又称为电梯调度算法。SCAN算法对最近扫描过的区域不公平,因此,它在访问局部性方面不如FCFS算法和SSTF算法好。
(3)循环扫描算法:CSCAN算法,来看一下上一种算法,有什么问题。仔细一看,我们会发现,在扫描到最里面的要求服务的序列时,接着会反向,在接下来的很大一部分时间里,应该是没有要求服务的磁道号的,因为之前已经访问过了。什么意思,就是说从初始磁道号到最里层的一个磁道号之间的所有序列都已经访问过了,所以SCAN会增加等待的时间。为了解决这样的情况,CSCAN算法的思想是,访问完最里面一个要求服务的序列之后,立即回到最外层欲访问磁道。也就是始终保持一个方向。故也称之为单向扫描调度算法。从最里面的一个磁道立即回到最外层欲访问的磁道,这步的距离是两者磁道号差的绝对值。
3.源代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#define MAX 100
using namespace std;
//求平均寻道长度
double pinjun(int length[],int n){
double sum=0;
int i;
for(i=0;i<n;i++)
sum+=length[i];
return sum/n;
}
//最短寻道时间优先算法
void SSTF(int a[],int n,int now){
int i,min,k=0;
int flag;//最短路径的下标
int t=n;
int next[MAX],length[MAX];
int visit[MAX]={0};//访问数组,已经访问过的为1
//寻道n次
while(t--){
min=999999;
//找没有访问过的中最近的
for(i=0;i<n;i++){
if(visit[i])
continue;
if(abs(a[i]-now)<min){
flag=i;
min=abs(a[i]-now);
}
}
length[k]=min;//移动的距离
next[k++]=a[flag];//下一个被访问的磁道号
visit[flag]=1;//访问过的置1
now=a[flag];//磁道移动到当前位置
}
cout<<endl<<"下一个磁道 "<<"移动距离"<<endl;
for(i=0;i<n;i++)
cout<<next[i]<<" "<<length[i]<<endl;
cout<<"平均寻道长度:";
printf("%.2f\n\n",pinjun(length,n));
}
//扫描算法
void SCAN(int a[],int n,int now){
int i,flag=0,k=0;
int next[MAX],length[MAX];
sort(a,a+n);//从小到大排序
//寻找开始磁道
for(i=0;i<n;i++){
if(a[i]>=now){
flag=i;
break;
}
}
//往递增方向访问
for(i=flag;i<n;i++){
next[k]=a[i];
length[k++]=abs(a[i]-now);
now=a[i];
}
//回来往递减方向访问
for(i=flag-1;i>=0;i--){
next[k]=a[i];
length[k++]=abs(a[i]-now);
now=a[i];
}
cout<<endl<<"下一个磁道 "<<"移动距离"<<endl;
for(i=0;i<n;i++)
cout<<next[i]<<" "<<length[i]<<endl;
cout<<"平均寻道长度:";
printf("%.2f\n\n",pinjun(length,n));
}
void CSCAN(int a[],int n,int now){
int i,flag=0,k=0;
int next[MAX],length[MAX];
sort(a,a+n);//从小到大排序
for(i=0;i<n;i++){
if(a[i]>=now){
flag=i;
break;
}
}
//往递增方向访问
for(i=flag;i<n;i++){
next[k]=a[i];
length[k++]=abs(a[i]-now);
now=a[i];
}
//循环往递增方向访问
for(i=0;i<flag;i++){
next[k]=a[i];
length[k++]=abs(a[i]-now);
now=a[i];
}
cout<<endl<<"下一个磁道 "<<"移动距离"<<endl;
for(i=0;i<n;i++)
cout<<next[i]<<" "<<length[i]<<endl;
cout<<"平均寻道长度:";
printf("%.2f\n\n",pinjun(length,n));
}
int main(){
int a[MAX];//存放要用到的磁道号
int start;//开始的磁道
int n,i,flag=1;
cout<<"一共要用到的磁道数:"<<endl;
cin>>n;
cout<<"每个磁道:"<<endl;
for(i=0;i<n;i++)
cin>>a[i];
cout<<"开始的磁道:"<<endl;
cin>>start;
//磁盘调度目录
while(flag){
cout<<"请选一种磁盘调度算法:"<<endl;;
cout<<"1.最短寻道时间优先"<<endl;
cout<<"2.扫描算法"<<endl;
cout<<"3.循环扫描算法"<<endl;
cout<<"0.退出"<<endl;
cin>>flag;
switch(flag){
case 1:
SSTF(a,n,start);break;
case 2:
SCAN(a,n,start);break;
case 3:
CSCAN(a,n,start);break;
case 0:
break;
}
}
return 0;
}