磁盘调度算法
FCFS
将需要分配的先来先分配。算法实现,直接计算每两个之间磁盘移动的距离。取一个绝对值。
void FCFS(){
cout<<"FCFS: \n";
int pre=100;
cout<<"\n从100号磁道开始\n\n";
cout<<"下一个磁道号 移动距离\n"<<endl;
int sum=0;
for(int i=1;i<len;i++){
cout<<" "<<q[i]<<" "<<abs(q[i]-q[i-1])<<endl;
sum+=abs(q[i]-q[i-1]);
}
cout<<"总移动长度 "<<sum<<endl;
cout<<"平均寻道长度 "<<(double)(sum*1.0/(len-1))<<endl;
}
SSTF
FCFS的平均寻到距离较大。SSTF算法会选择要求访问的磁道与当前磁头所在的磁道距离最近的。
算法实现:用循环暴力去未分配磁盘的作业序列里找和当前最近的。
void SSTF(){
cout<<"SSTF: \n";
int pre=100,cnt=0,sum=0;
bool vis[1010];
for(int i=0;i<len;i++) vis[i]=false;
cout<<"下一个磁道号 移动距离\n"<<endl;
vis[0]=true;
while(cnt<len-1){
int pos=0,mi=1e9;
for(int i=1;i<len;i++){
if(abs(q[i]-pre)<mi&&!vis[i]){
pos=i;
mi=abs(q[i]-pre);
}
}
cout<<q[pos]<<" "<<mi<<endl;
pre=q[pos];
vis[pos]=true;
sum+=mi;
cnt++;
}
cout<<"总移动长度 "<<sum<<endl;
cout<<"平均寻道长度 "<<(double)(sum*1.0/(len-1))<<endl;
}
电梯磁盘调度算法 SCAN
固定一个方向,扫描到边界,到边界之后在回到另一边。
算法实现:将序列排好序,找到起始位置,固定开始方向向右,循环向右,然后再循环向左。
void SCAN(){
cout<<"SCAN:"<<endl;
sort(q,q+len);
int start=-1;
bool vis[1001];
for(int i=0;i<len;i++) vis[i]=false;
//假设起始点是100,找到排序后100的位置,采用优先向右走
for(int i=0;i<len;i++){
if(q[i]==100) {
start=i;
vis[i]=true;
break;
}
}
cout<<"下一个磁道号 移动距离\n"<<endl;
int sum=0;
for(int i=start+1;i<len;i++){
cout<<q[i]<<" "<<q[i]-q[i-1]<<endl;
sum+=q[i]-q[i-1];
}
cout<<q[start-1]<<" "<<q[len-1]-q[start-1]<<endl;
sum+=q[len-1]-q[start-1];
for(int i=start-2;i>=0;i--){
cout<<q[i]<<" "<<q[i+1]-q[i]<<endl;
sum+=q[i+1]-q[i];
}
cout<<"总移动长度 "<<sum<<endl;
cout<<"平均寻道长度 "<<(double)(sum*1.0/(len-1))<<endl;
}
实验九 磁盘调度算法的模拟
使用C语言完成磁盘调度算法中的最短寻道时间优先调度算法和电梯调度算法!假设进程请求的访问磁盘的磁道序列号为:100 55 58 39 18 90 160 150 38 184请输出采用不同算法时访问的磁道号,并计算平均寻道长度。请提交源代码和运行结果截图!
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int len=0,x;//len表示序列的长度
int q[N];//存储作业序列
/*
作业序列,以下作业起点均假设为100,和书上P242一致
100 55 58 39 18 90 160 150 38 184 -1
*/
void FCFS(){
cout<<"FCFS: \n";
int pre=100;
cout<<"\n从100号磁道开始\n\n";
cout<<"下一个磁道号 移动距离\n"<<endl;
int sum=0;
for(int i=1;i<len;i++){ //循环遍历一遍即可
cout<<" "<<q[i]<<" "<<abs(q[i]-q[i-1])<<endl;
sum+=abs(q[i]-q[i-1]);
}
cout<<"总移动长度 "<<sum<<endl;
cout<<"平均寻道长度 "<<(double)(sum*1.0/(len-1))<<endl;//序列长度为len,寻道len-1次。
}
void SSTF(){
cout<<"SSTF: \n";
int pre=100,cnt=0,sum=0;
bool vis[1010];
for(int i=0;i<len;i++) vis[i]=false;
cout<<"下一个磁道号 移动距离\n"<<endl;
vis[0]=true;
while(cnt<len-1){
int pos=0,mi=1e9;
for(int i=1;i<len;i++){//两重循环,每一次都循环找和当前最近的,这里其实可以二分的,但是这种作业没必要。
if(abs(q[i]-pre)<mi&&!vis[i]){
pos=i;
mi=abs(q[i]-pre);
}
}
cout<<q[pos]<<" "<<mi<<endl;
pre=q[pos];
vis[pos]=true;
sum+=mi;
cnt++;
}
cout<<"总移动长度 "<<sum<<endl;
cout<<"平均寻道长度 "<<(double)(sum*1.0/(len-1))<<endl;//序列长度为len,寻道len-1次。
}
void SCAN(){
cout<<"SCAN:"<<endl;
sort(q,q+len);
int start=-1;
bool vis[1001];
for(int i=0;i<len;i++) vis[i]=false;
//假设起始点是100,找到排序后100的位置,采用优先向右走
for(int i=0;i<len;i++){
if(q[i]==100) {
start=i;
vis[i]=true;
break;
}
}
cout<<"下一个磁道号 移动距离\n"<<endl;
int sum=0;
for(int i=start+1;i<len;i++){//向右扫描
cout<<q[i]<<" "<<q[i]-q[i-1]<<endl;
sum+=q[i]-q[i-1];
}
cout<<q[start-1]<<" "<<q[len-1]-q[start-1]<<endl;
sum+=q[len-1]-q[start-1];//回到左边最近需要分配的作业
for(int i=start-2;i>=0;i--){//循环向左扫描
cout<<q[i]<<" "<<q[i+1]-q[i]<<endl;
sum+=q[i+1]-q[i];
}
cout<<"总移动长度 "<<sum<<endl;
cout<<"平均寻道长度 "<<(double)(sum*1.0/(len-1))<<endl;//序列长度为len,寻道len-1次。
}
int main(){
printf("请输入进程请求的访问磁盘的磁道序列号(输入-1结束)\n");
while(cin>>x){
if(x==-1) break;
q[len++]=x;
}
FCFS();
cout<<"\n<---------------------------->\n"<<endl;
SSTF();
cout<<"\n<---------------------------->\n"<<endl;
SCAN();
}
实现截图:
总结:实现的比较简单,有很多小细节没有具体去细化。