操作系统实验四:磁盘调度算法
时间:20##-12-20
地点:计算机实验机房2
实验人:朱蓉蓉 学号:E01114336
本次实验主要进行磁盘调度算法中的FCFS.SSTF,SCAN算法的编程。
实验代码如下:
#include<iostream>
#include<stdio.h>
#include<iomanip>
#include<math.h>
using namespace std;
const int Max=100;
int TrackOrder[Max]; //磁道号
int MoveDistance[Max]; //----移动距离;
int FindOrder[Max]; //-----寻好序列。
double AverageDistance; //-----平均寻道长度
bool direction; //-----方向 true时为向外,false为向里
int BeginNum; //----开始磁道号。
int M; //----磁道数。
int N; //-----提出磁盘I/O申请的进程数
int SortOrder[Max]; //----排序后的序列
bool Finished[Max];
void Inith()
{
cout<<"请输入磁道数:";
cin>>M;
cout<<"请输入提出磁盘I/O申请的进程数:";
cin>>N;
cout<<"请依次输入要访问的磁道号:";
for(int i=0;i<N;i++)
cin>>TrackOrder[i];
for(int j=0;j<N;j++)
MoveDistance[j]=0;
cout<<"请输入开始磁道号:";
cin>>BeginNum;
for(int k=0;k<N;k++)
Finished[k]=false;
for(int l=0;l<N;l++)
SortOrder[l]=TrackOrder[l];
}
//=====================排序函数,将各进程申请的磁道按从小到大排列=================
void Sort()
{ //------冒泡排序
int temp;
for(int i=N-1;i>=0;i--)
for(int j=0;j<i;j++)
{
if(SortOrder[j]>SortOrder[j+1])
{
temp=SortOrder[j];
SortOrder[j]=SortOrder[j+1];
SortOrder[j+1]=temp;
}
}
}
//============先来先服务=================================
void FCFS()
{
int temp;
temp=BeginNum; //--------将BeginNum赋给temp作为寻道时的当前所在磁道号
for(int i=0;i<N;i++)
{
MoveDistance[i]=abs(TrackOrder[i]-temp); //-------计算移动磁道数
temp=TrackOrder[i]; //-------寻到后,将此道作为当前所在磁道号,赋给temp
FindOrder[i]=TrackOrder[i]; //-----寻好的赋给寻好序列
}
}
//========最短寻道法=============================
void SSTF()
{
int temp,n;
int A=M;
temp=BeginNum; //--------将BeginNum赋给temp作为寻道时的当前所在磁道号
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++) //-------寻找最短的寻道长度
{
if(abs(TrackOrder[j]-temp)<A&&Finished[j]==false)
{
A=abs(TrackOrder[j]-temp);
n=j;
}
else continue;
}
Finished[n]=true; //-------将已经寻找到的Finished赋值为true
MoveDistance[i]=A; //-------寻道长度
temp=TrackOrder[n]; //-------当前寻道号。
A=M; //-----重置A值
FindOrder[i]=TrackOrder[n]; //----寻好的赋给寻好序列
}
}
//=====================SCAN,扫描算法==========================
void SCAN()
{
int m,n,temp;
temp=BeginNum;
Sort(); //------排序
cout<<"请选择开始方向:1--向外;0---向里"; //------选择扫描方向
cin>>m;
if(m==1)
direction=true;
else if(m==0)
direction=false;
else
cout<<"输入错误";
for(int i=0;i<N;i++)
{
if(SortOrder[i]<BeginNum)
continue;
else
{
n=i;
break;
}
}
if(direction==true) //------选择向外
{
for(int i=n;i<N;i++)
{
MoveDistance[i-n]=abs(SortOrder[i]-temp);
temp=SortOrder[i];
FindOrder[i-n]=SortOrder[i];
}
for(int j=n-1;j>=0;j--)
{
MoveDistance[N-1-j]=abs(SortOrder[j]-temp);
temp=SortOrder[j];
FindOrder[N-1-j]=SortOrder[j];
}
}
else //-------选择向里
{
for(int i=n-1;i>=0;i--)
{
MoveDistance[N-i-4]=abs(SortOrder[i]-temp);
temp=SortOrder[i];
FindOrder[N-i-4]=SortOrder[i];
}
for(int j=n;j<N;j++)
{
MoveDistance[j]=abs(SortOrder[j]-temp);
temp=TrackOrder[j];
FindOrder[j]=SortOrder[j];
}
}
}
//========计算平均寻道时间==============
void Count()
{
int Total=0;
for(int i=0;i<N;i++)
{
Total+=MoveDistance[i];
}
AverageDistance=((double)Total)/((double)N);
}
void Show()
{
cout<<"================从"<<BeginNum<<"号磁道开始====================="<<endl;
cout<<setw(20)<<"被访问的下一个磁道号"<<setw(20)<<"移动距离(磁道数)"<<endl;
for(int i=0;i<N;i++)
{
cout<<setw(15)<<FindOrder[i]<<setw(15)<<MoveDistance[i]<<endl;
}
cout<<setw(20)<<"平均寻道长度:"<<AverageDistance<<endl;
cout<<endl;
}
int main()
{
int y=1;
int s;
Inith();
while(y)
{
cout<<endl;
cout<<"**********************************************"<<endl;
cout<<"****** 磁盘调度算法 ******"<<endl;
cout<<"**********************************************"<<endl;
cout<<"*** ***"<<endl;
cout<<"** 1. 先来先服务 **"<<endl;
cout<<"** **"<<endl;
cout<<"** 2. 最短寻道时间优先 **"<<endl;
cout<<"** **"<<endl;
cout<<"** 3. 扫描调度 **"<<endl;
cout<<"*** ***"<<endl;
cout<<"**********************************************"<<endl;
cout<<"**********************************************"<<endl;
cout<<"请选择算法:";
cin>>s;
switch(s)
{
case 1:FCFS();Count();Show();break;
case 2:SSTF();Count();Show();break;
case 3:SCAN();Count();Show();break;
}
cout<<"是否继续选择寻道算法?1--是;2--否";
int p;
cin>>p;
y=p;
}
return 0;
}
实验结果截图:
FCFS:
SSTF:
SCAN 向外
SCAN 向内
第二篇:操作系统磁盘调度算法
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define N 20
typedef struct
{
int num;//磁道
int flag;//1个标记量
}V,*v;
//********************************************************************* void Initial(v *a,int n)
{//初始化磁道请求
printf("请输入请求顺序(磁道范围是0 - 199):\n");
for(int i = 1;i <= n;i++)
{
a[i] = (v)malloc(sizeof(V));
if(!a[i]) exit(-1);
scanf("%d",&a[i]->num);
a[i]->flag = 0;
}
}
//*********************************************************************** void FCFS(v *a,int start,int n)
{//先到先服务算法
int temp = start;
float s = 0;
printf("---------------------------FCFS调度算法----------------------------\n"); for(int i = 1;i <= n; i++)
{
temp = abs(a[i]->num - temp);
s += temp;
a[i]->flag = i;
temp = a[i]->num;
}
int temp2;
for(i = n;i >= 1;i--)
{//冒泡排序,按照磁道访问的先后顺序重新排列数组a,用于输出调度顺序 for(int j = 1;j < i;j ++)
{
if(a[j]->flag> a[j+1]->flag)
{
temp = a[j]->flag;
temp2 = a[j]->num;
a[j]->flag = a[j+1]->flag;
a[j]->num = a[j+1]->num;
a[j+1]->flag = temp;
a[j+1]->num = temp2;
}
}
}
printf("调度序列为:\n");
printf("%d—>",start);
for(i = 1;i <= n; i++)
{
printf("%d —> ",a[i]->num);
}
printf("\n");
printf("寻道长度是%f",s);printf("\n");
printf("平均寻道长度是%f",s/n);
printf("\n");
printf("---------------------------FCFS调度算法----------------------------\n");
}
//************************************************************************ int Find(v *a,int n,int start)
{//找到离开始磁道最近的一项,返回下标
int p;
for(int i = 1;i < n;i++)
{
if((a[i]->num <= start) && (start <=a[i+1]->num ))
{
if(abs(a[i]->num - start) < abs(a[i+1]->num - start))
{
p = i;
}
else
{
p= i+1;
}
}
}
return p;
}
void SSTF(v *a,int start,int n)
{//最短寻道时间调度算法
int temp;
int pr,pl;//分别标记离磁头最近的那个磁道在数组中的下标的前一个和后一个 float s = 0; //用来计算寻道长度 temp = start; printf("---------------------------SSTF调度算法----------------------------\n"); for(int i = n;i >= 1;i--) {//冒泡排序,把磁道按由小到大的顺序排列 for(int j = 1;j < i;j ++) { if(a[j]->num > a[j+1]->num) { temp = a[j]->num; a[j]->num = a[j+1]->num; a[j+1]->num = temp; } } } printf("排序后\n"); for(int j=1;j<=n;j++) printf("%d ",a[j]->num); printf("\n"); int p,x; p = Find(a,n,start); x = p; pr = p + 1; pl = p - 1; if(start <= a[1]->num) {//磁头在最左边 s =(float)(a[1]->num-start); printf("调度序列为:\n"); printf("%d—>",start); for(i = 1;i <= n; i++) { if(i!=1) { s+=a[i]->num-a[i-1]->num; } printf("%d —> ",a[i]->num); } printf("\n"); printf("寻道长度为%f",s); printf("\n"); printf("平均寻道长度是%f",s/n); printf("\n"); }
else if(start >= a[n]->num) {//磁头在最右边 s =(float)(start-a[n]->num); printf("调度序列为:\n"); printf("%d—>",start); for(i = n; i >= 1; i--) { if(i!=1) { s += a[i]->num-a[i-1]->num; } printf("%d —> ",a[i]->num); } printf("\n"); printf("寻道长度为%f",s); printf("平均寻道长度是%f",s/n); printf("\n"); } else {//磁头在中间 printf("调度序列为:\n"); printf("%d—>",start); printf("%d —> ",a[p]->num); s = (float)(a[p]->num - start); while(1) { if(abs(a[pl]->num - a[p]->num) <= abs(a[p]->num - a[pr]->num)) { s += a[p]->num-a[pl]->num; p = pl; printf("%d —> ",a[p]->num); pl--; if(pl==0) { s += a[pr]->num-a[1]->num; s += a[n]->num-a[pr]->num; for(int i=pr;i<=n;i++) { printf(" %d—>",a[i]->num); } break; } }
else
{
s += a[pr]->num-a[p]->num;
p = pr;
printf("%d —> ",a[p]->num);
pr++;
if(pr==n+1)
{
s += a[n]->num-a[pl]->num;
s += a[pl]->num-a[1]->num;
for(int i=pl;i>=1;i--)
{
printf("%d —> ",a[i]->num);
}
break;
}
}
}
printf("\n");
printf("寻道长度为%f",s);
printf("\n");
printf("平均寻道长度是%f",s/n);
printf("\n");
}
printf("---------------------------SSTF调度算法----------------------------\n");
}
//********************************************************************** void SCAN(v *a,int start,int n)
{//电梯算法
int l = 0 ;//用于设置访问磁道的flag
int temp,temp2;
for(int i = n;i >= 1;i--)
{//冒泡排序,把磁道按由小到大的顺序排列
for(int j = 1;j < i;j ++)
{
if(a[j]->num > a[j+1]->num)
{
temp = a[j]->num;
a[j]->num = a[j+1]->num;
a[j+1]->num = temp;
}
}
} int p,x; p = Find(a,n,start); x = p; float s = 0; int toleft,toright; printf("---------------------------SCAN调度算法----------------------------\n"); if(abs(start - a[1]->num) < abs(a[n]->num - start)) toleft = 1;//磁头离最左端的磁道近 else toright = 1;//磁头离最右端的磁道近 temp = start; if(toleft == 1) {//先向0磁道方向访问 while(p != 0) { temp = abs(a[p]->num - temp); s += temp; l += 1; temp = a[p]->num; a[p]->flag = l; p--; } s += a[1]->num - 0; temp = 0; x = x + 1; while(x != n) { temp = abs(a[x]->num - temp); s += temp; l += 1; temp = a[x]->num; a[x]->flag =l; x++; } for(i = n;i >= 1;i--) {//冒泡排序,按照访问的顺序将数组重新排列 for(int j = 1;j < i;j ++) { if(a[j]->flag> a[j+1]->flag) { temp = a[j]->flag; temp2 = a[j]->num; a[j]->flag = a[j+1]->flag;
a[j]->num = a[j+1]->num; a[j+1]->flag = temp; a[j+1]->num = temp2; } } } printf("调度序列为:\n"); printf("%d—>",start); for(i = 1;i <= n; i++) { printf("%d —> ",a[i]->num); } printf("\n"); printf("寻道长度是%f",s);printf("\n"); printf("平均寻道长度是%f",s/n); printf("\n"); } if(toright == 1) {//先向199磁道方向访问 while(p != n+1) { temp = abs(a[p]->num - temp); s += temp;l += 1; temp = a[p]->num; a[p]->flag = l; p++; } s += abs(199 - a[n]->num); temp = 199; x = x - 1; while(x != 0) { temp = abs(a[x]->num - temp); s += temp; l += 1; temp = a[x]->num; a[x]->flag =l; x--; } for(i = n;i >= 1;i--) {//冒泡排序,按照访问的顺序将数组重新排列 for(int j = 1;j < i;j ++) { if(a[j]->flag> a[j+1]->flag)
{
temp = a[j]->flag;
temp2 = a[j]->num;
a[j]->flag = a[j+1]->flag;
a[j]->num = a[j+1]->num;
a[j+1]->flag = temp;
a[j+1]->num = temp;
}
}
}
printf("调度序列为:\n");
printf("%d—>",start);
for(i = 1;i <= n; i++)
{
printf("%d —> ",a[i]->num);
}
printf("\n");
printf("寻道长度是%f",s);printf("\n");
printf("平均寻道长度是%f",s/n);
printf("\n");
}
printf("---------------------------SCAN调度算法----------------------------\n");
}
//*************************************************************************
void CSCAN(v *a,int start,int n)
{//
int temp,temp2;
int l = 0;
for(int i = n;i >= 1;i--)
{//冒泡排序
for(int j = 1;j < i;j ++)
{
if(a[j]->num > a[j+1]->num)
{
temp = a[j]->num;
a[j]->num = a[j+1]->num;
a[j+1]->num = temp;
}
}
}
int p,x; p = Find(a,n,start); x = p; float s = 0; temp = start; printf("---------------------------CSCAN调度算法----------------------------\n"); if((n - p) >= p ) {//右边的磁道数比左边的磁道数多 while(p != n+1) { temp = abs(a[p]->num - temp); s += temp;l += 1; temp = a[p]->num;a[p]->flag = l; p++; } s += abs(199 - a[n]->num); temp = 0; x = x + 1; i = 1; while(i != x) { temp = abs(a[i]->num - temp); s += temp;l += 1; temp = a[i]->num; a[i]->flag = l; i++; } for(i = n;i >= 1;i--) {//冒泡排序,按照访问的顺序将数组重新排列 for(int j = 1;j < i;j ++) { if(a[j]->flag> a[j+1]->flag) { temp = a[j]->flag; temp2 = a[j]->num; a[j]->flag = a[j+1]->flag; a[j]->num = a[j+1]->num; a[j+1]->flag = temp; a[j+1]->num = temp2; } } } printf("调度序列为:\n"); printf("%d—>",start);
for(i = 1;i <= n; i++) { printf("%d —> ",a[i]->num); } printf("\n"); printf("寻道长度是%f",s);printf("\n"); printf("平均寻道长度是%f",s/n); printf("\n"); } else {//左边的磁道数比右边的磁道数多 while(p != 0) { temp = abs(a[p]->num - temp); s += temp;l += 1; temp = a[p]->num; a[p]->flag = l; p--; } s += a[1]->num - 0; temp = 199; i = n; while(i != x) { temp = abs(a[i]->num - temp); s += temp; temp = a[i]->num;l += 1; a[i]->flag =l; i--; } for(i = n;i >= 1;i--) {//冒泡排序,按照访问的顺序将数组重新排列 for(int j = 1;j < i;j ++) { if(a[j]->flag> a[j+1]->flag) { temp = a[j]->flag; temp2 = a[j]->num; a[j]->flag = a[j+1]->flag; a[j]->num = a[j+1]->num; a[j+1]->flag = temp; a[j+1]->num = temp2; } }
}
printf("调度序列为:\n");
printf("%d—>",start);
for(i = 1;i <= n; i++)
{
printf("%d —> ",a[i]->num);
}
printf("\n");
printf("寻道长度是%f",s);printf("\n");
printf("平均寻道长度是%f",s/n);
printf("\n");
}
printf("---------------------------CSCAN调度算法----------------------------\n"); }
//************************************************************************** void main()
{
int n;//
v a[N];
int start;//磁头开始的位置
int choice;//用于标记操作的序号
printf("******************************磁盘调度算****************************\n");
printf(" ");printf("1.FCFS调度算法\n");
printf(" ");printf("2.SSTF调度算法\n");
printf(" ");printf("3.SCAN调度算法\n");
printf(" ");printf("4.CSCAN调度算法\n");
printf(" ");printf("5.退出\n");
printf("******************************磁盘调度算****************************\n");
printf("请输入请求的柱面数 :");
scanf("%d",&n);
printf("请输入磁头开始的位置:");
scanf("%d",&start);
Initial(a,n);
while(1)
{
printf("请选择你要的操作序号\n");
scanf("%d",&choice);
switch(choice){
case 1:FCFS(a,start,n);break;
case 2:SSTF(a,start,n);break;
case 3:SCAN(a,start,n);break; 法法
} } case 4:CSCAN(a,start,n);break; case 5:exit(-1); default:printf("你输入的操作序号有误!"); } printf("\n");