磁盘调度 操作系统实验报告
- 格式:doc
- 大小:145.50 KB
- 文档页数:20
实验一磁盘调度算法实现一、实验目得本课程设计得目得就是通过磁盘调度算法设计一个磁盘调度模拟系统,从而使磁盘调度算法更加形象化,容易使人理解,使磁盘调度得特点更简单明了,能使使用者加深对先来先服务算法、最短寻道时间优先算法、扫描算法以及循环扫描算法等磁盘调度算法得理解。
二、实验内容系统主界面可以灵活选择某种算法,算法包括:先来先服务算法(FCFS)、最短寻道时间优先算法(SSTF)、扫描算法(SCAN)、循环扫描算法(CSCAN)。
2、1先来先服务算法( FCFS )这就是一种比较简单得磁盘调度算法。
它根据进程请求访问磁盘得先后次序进行调度。
此算法得优点就是公平、简单,且每个进程得请求都能依次得到处理,不会出现某一进程得请求长期得不到满足得情况。
此算法由于未对寻道进行优化,在对磁盘得访问请求比较多得情况下,此算法将降低设备服务得吞吐量,致使平均寻道时间可能较长,但各进程得到服务得响应时间得变化幅度较小。
2、2最短寻道时间优先算法( SSTF)该算法选择这样得进程,其要求访问得磁道与当前磁头所在得磁道距离最近,以使每次得寻道时间最短,该算法可以得到比较好得吞吐量,但却不能保证平均寻道时间最短.其缺点就是对用户得服务请求得响应机会不就是均等得,因而导致响应时间得变化幅度很大。
在服务请求很多得情况下,对内外边缘磁道得请求将会无限期得被延迟,有些请求得响应时间将不可预期。
2、3 扫描算法( SCAN )扫描算法不仅考虑到欲访问得磁道与当前磁道得距离,更优先考虑得就是磁头得当前移动方向。
例如,当磁头正在自里向外移动时,扫描算法所选择得下一个访问对象应就是其欲访问得磁道既在当前磁道之外,又就是距离最近得。
这样自里向外地访问,直到再无更外得磁道需要访问才将磁臂换向,自外向里移动。
这时,同样也就是每次选择这样得进程来调度,即其要访问得磁道,在当前磁道之内,从而避免了饥饿现象得出现。
由于这种算法中磁头移动得规律颇似电梯得运行,故又称为电梯调度算法。
此算法基本上克服了最短寻道时间优先算法得服务集中于中间磁道与响应时间变化比较大得缺点,而具有最短寻道时间优先算法得优点即吞吐量较大,平均响应时间较小,但由于就是摆动式得扫描方法,两侧磁道被访问得频率仍低于中间磁道。
2、4循环扫描算法( CSCAN )循环扫描算法就是对扫描算法得改进。
如果对磁道得访问请求就是均匀分布得,当磁头到达磁盘得一端,并反向运动时落在磁头之后得访问请求相对较少.这就是由于这些磁道刚被处理,而磁盘另一端得请求密度相当高,且这些访问请求等待得时间较长,为了解决这种情况,循环扫描算法规定磁头单向移动。
例如,只自里向外移动,当磁头移到最外得被访问磁道时,磁头立即返回到最里得欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描。
三、实验流程3、1 系统功能图图3-1系统功能图3、2算法流程图本次实验为实现磁盘调度算法,分别实现四个算法并调试。
四个算法算法包括:先来先服务算法(FCFS)、最短寻道时间优先算法(SSTF)、扫描算法(SCA N)、循环扫描算法(CSCAN)。
四个算法得流程图分析如下。
1)先来先服务算法(FCFS)得流程图图3-2先来先服务算法得流程图2)最短寻道时间优先算法(SSTF)得流程图图3—3最短寻道时间优先算法得流程图3)扫描算法(SCAN)得流程图图3-4扫描算法得流程图4)循环扫描算法(CSCAN)得流程图图3-5循环扫描算法得流程图四、源程序#include〈stdio、h>#include<stdlib、h>#include<iostream、h>#include<math、h>#define maxsize1000/*********************判断输入数据就是否有效**************************/intdecide(char str[])//判断输入数据就是否有效{int i=0;while(str[i]!='\0'){if(str[i]<'0’||str[i]>’9’){ﻩﻩreturn0;ﻩﻩﻩbreak;}ﻩi++;}return i;}/******************将字符串转换成数字***********************/inttrans(charstr[],int a)//将字符串转换成数字{inti;ﻩint sum=0;ﻩfor(i=0;i<a;i++) sum=sum+(int)((str[i]-'0')*pow(10,a—i—1));return sum;}/*********************冒泡排序算法**************************/int *bubble(int cidao[],int m){int i,j;ﻩint temp;ﻩfor(i=0;i<m;i++) //使用冒泡法按从小到大顺序排列ﻩfor(j=i+1;j<m;j++){ﻩif(cidao[i]>cidao[j]){ﻩﻩtemp=cidao[i];ﻩﻩcidao[i]=cidao[j];ﻩﻩcidao[j]=temp;ﻩ}}ﻩcout<〈” 排序后得磁盘序列为:”;ﻩfor( i=0;i<m;i++) //输出排序结果cout<〈cidao[i]<<” ”;cout<<endl;return cidao;}/*********************先来先服务调度算法**************************/voidFCFS(int cidao[],int m)//磁道号数组,个数为m{int now;//当前磁道号intsum=0; //总寻道长度int j,i;int a;ﻩchar str[100];ﻩfloat ave; //平均寻道长度ﻩcout<<” 磁盘请求序列为:”;for( i=0;i〈m;i++)//按先来先服务得策略输出磁盘请求序列cout<<cidao[i]〈〈” ";cout〈<endl;ﻩcout<〈"请输入当前得磁道号:";B: cin〉〉str; //对输入数据进行有效性判断ﻩa=decide(str);ﻩif(a==0){ﻩcout<<"输入数据得类型错误,请重新输入!”〈<endl;ﻩgoto B;}ﻩelseﻩnow=trans(str,a);//输入当前磁道号ﻩsum+=abs(cidao[0]-now);ﻩcout<<"磁盘扫描序列为:";for(i=0;i〈m;i++) //输出磁盘扫描序列ﻩﻩcout〈<cidao[i]<〈” ";ﻩfor(i=0,j=1;j<m;i++,j++)//求平均寻道长度ﻩ{sum+=abs(cidao[j]-cidao[i]);ﻩave=(float)(sum)/(float)(m);ﻩ}ﻩcout〈〈endl;cout<<"平均寻道长度:”〈<ave<<endl;}/**********************最短寻道时间优先调度算法********************/void SSTF(int cidao[],int m){ﻩintk=1;ﻩint now,l,r;ﻩinti,j,sum=0;ﻩinta;char str[100];float ave;cidao=bubble(cidao,m); //调用冒泡排序算法排序ﻩcout〈〈"请输入当前得磁道号:”;C:cin>〉str; //对输入数据进行有效性判断a=decide(str);ﻩif(a==0){cout<<"输入数据得类型错误,请重新输入!"<<endl;ﻩgoto C;}ﻩelseﻩnow=trans(str,a);//输入当前磁道号ﻩif(cidao[m-1]〈=now) //若当前磁道号大于请求序列中最大者,则直接由外向内依次给予各请求服务{cout〈<" 磁盘扫描序列为:”;ﻩfor(i=m—1;i>=0;i--)ﻩcout<〈cidao[i]<<” ";ﻩsum=now-cidao[0];ﻩ}if(cidao[0]>=now)//若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务ﻩ{cout<<”磁盘扫描序列为:";for(i=0;i<m;i++)ﻩcout<<cidao[i]〈〈" ";sum=cidao[m-1]-now;}if(now>cidao[0]&&now〈cidao[m-1])//若当前磁道号大于请求序列中最小者且小于最大者ﻩ{ﻩﻩcout<<”磁盘扫描序列为:”;ﻩﻩwhile(cidao[k]<now) //确定当前磁道在已排得序列中得位置,后面得算法都用到了,可以直接复制后少量修改,节省时间。
ﻩﻩk++;ﻩl=k-1;ﻩr=k;ﻩwhile((l〉=0)&&(r<m))//当前磁道在请求序列范围内ﻩ{ﻩif((now—cidao[l])<=(cidao[r]-now))//选择与当前磁道最近得请求给予服务ﻩ{ﻩﻩﻩcout〈〈cidao[l]〈〈” ";ﻩsum+=now-cidao[l];ﻩﻩnow=cidao[l];ﻩﻩﻩl=l—1;}ﻩelse{ﻩﻩcout<<cidao[r]〈<” ";ﻩsum+=cidao[r]-now;ﻩﻩﻩnow=cidao[r];ﻩﻩﻩﻩr=r+1;ﻩ}ﻩ}}if(l==—1)//磁头移动到序列得最小号,返回外侧扫描仍未扫描得磁道{for(j=r;j<m;j++)ﻩcout<<cidao[j]<〈” ";ﻩsum+=cidao[m—1]-cidao[0];}ﻩelse //磁头移动到序列得最大号,返回内侧扫描仍未扫描得磁道ﻩ{ﻩﻩfor(j=l;j>=0;j--) cout〈<cidao[j]<<" ”;ﻩsum+=cidao[m—1]—cidao[0];}ave=(float)(sum)/(float)(m);ﻩcout<〈endl;ﻩcout〈<"平均寻道长度:”<<ave〈<endl;}/*****************************扫描调度算法*******************************/void SCAN(intcidao[],int m)//先要给出当前磁道号与移动臂得移动方向{intk=1;ﻩintnow,l,r,d;int i,j,sum=0;ﻩint a;char str[100];ﻩfloat ave;ﻩcidao=bubble(cidao,m); //调用冒泡排序算法排序cout〈<"请输入当前得磁道号:";D:cin〉>str;//对输入数据进行有效性判断a=decide(str);ﻩif(a==0){ﻩcout<<"输入数据得类型错误,请重新输入!"<<endl;ﻩgoto D;ﻩ}else now=trans(str,a); //输入当前磁道号if(cidao[m-1]<=now) //若当前磁道号大于请求序列中最大者,则直接由外向内依次给予各请求服务,此情况同最短寻道优先{ﻩcout〈<"磁盘扫描序列为:”;ﻩﻩfor(i=m-1;i>=0;i-—)cout<<cidao[i]<<" ”;ﻩsum=now-cidao[0];}ﻩif(cidao[0]>=now)//若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务,此情况同最短寻道优先ﻩ{ﻩcout<〈”磁盘扫描序列为:”;for(i=0;i<m;i++)ﻩcout〈〈cidao[i]<<" ”;sum=cidao[m-1]—now;}if(now>cidao[0]&&now<cidao[m-1])//若当前磁道号大于请求序列中最小者且小于最大者{ﻩﻩwhile(cidao[k]〈now) k++;ﻩl=k-1;ﻩr=k;ﻩﻩcout<〈” 请输入当前移动臂得移动得方向:\n”<〈endl;ﻩﻩcout<<"0:表示向内1 :表示向外: "<<endl;ﻩﻩcin>>d;if(d==0)//选择移动臂方向向内,则先向内扫描{ﻩcout<<" 磁盘扫描序列为:";ﻩfor(j=l;j>=0;j—-)ﻩcout〈〈cidao[j]<<” ";//输出向内扫描得序列ﻩfor(j=r;j<m;j++) //磁头移动到最小号,则改变方向向外扫描未扫描得磁道ﻩﻩcout<<cidao[j]<<”"; //输出向外扫描得序列sum=now—2*cidao[0]+cidao[m-1];ﻩ}ﻩelse //选择移动臂方向向外,则先向外扫描{ﻩﻩcout〈<” 磁盘扫描序列为:";ﻩﻩﻩfor(j=r;j<m;j++)ﻩcout<<cidao[j]<<"";//输出向外扫描得序列ﻩﻩfor(j=l;j>=0;j--) //磁头移动到最大号,则改变方向向内扫描未扫描得磁道ﻩﻩcout<〈cidao[j]〈〈"";ﻩﻩsum=-now-cidao[0]+2*cidao[m-1];}}ﻩﻩave=(float)(sum)/(float)(m);ﻩcout<<endl;ﻩcout〈〈” 平均寻道长度:”<<ave<<endl;}/************************循环扫描调度算法*****************************/void CSCAN(int cidao[],int m){int k=1;int now,l,r;ﻩint i,j,sum=0;ﻩinta;char str[100];float ave;cidao=bubble(cidao,m); //调用冒泡排序算法排序ﻩcout<<"请输入当前得磁道号:”;E:cin>>str;//对输入数据进行有效性判断ﻩa=decide(str);if(a==0){ﻩcout〈〈” 输入数据得类型错误,请重新输入!”<〈endl;gotoE;}elsenow=trans(str,a); //输入当前磁道号if(cidao[m—1]<=now)//若当前磁道号大于请求序列中最大者,则直接将移动臂移动到最小号磁道依次向外给予各请求服务ﻩ{cout〈<"磁盘扫描序列为:";for(i=0;i<m;i++)ﻩcout〈<cidao[i]〈<” ”;ﻩsum=now—2*cidao[0]+cidao[m—1];ﻩ}ﻩif(cidao[0]>=now)//若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务,此情况同最短寻道优先{cout<<"磁盘扫描序列为:";ﻩﻩfor(i=0;i<m;i++)c out<〈cidao[i]<<"”;sum=cidao[m-1]—now;}if(now〉cidao[0]&&now<cidao[m-1])//若当前磁道号大于请求序列中最小者且小于最大者{ﻩﻩcout<〈” 磁盘扫描序列为:";ﻩwhile(cidao[k]<now)//单向反复地从内向外扫描ﻩk++;ﻩﻩl=k—1;r=k;ﻩﻩfor(j=r;j<m;j++)ﻩcout<<cidao[j]〈<” ”; //输出从当前磁道向外扫描得序列ﻩfor(j=0;j〈r;j++)//当扫描完最大号磁道,磁头直接移动到最小号磁道,再向外扫描未扫描得磁道ﻩﻩcout<〈cidao[j]<<" ”;ﻩsum=2*cidao[m-1]+cidao[l]-now-2*cidao[0];ﻩ}ave=(float)(sum)/(float)(m);ﻩcout<<endl;ﻩcout〈<"平均寻道长度:”<<ave<<endl;}void main(){int a;ﻩintc;//菜单项intcidao[maxsize];int i=0,count;ﻩcharstr[100];ﻩcout<〈" 请输入磁道序列(输入0结束): "<〈endl;A:cin>>str;//对输入数据进行有效性判断ﻩa=decide(str);ﻩif(a==0){cout<<” 输入数据得类型错误,请重新输入!”<<endl;ﻩgoto A;//输入错误,跳转到A,重新输入ﻩ}ﻩelseﻩcidao[i]=trans(str,a);ﻩi++;while(cidao[i—1]!=0){ﻩﻩcin>>str;//对输入数据进行有效性判断ﻩa=decide(str);ﻩif(a==0)cout<〈"输入数据得类型错误,请重新输入!"<〈endl; ﻩﻩelse{ﻩﻩﻩcidao[i]=trans(str,a);ﻩﻩi++;ﻩ}ﻩ}ﻩcount=i-1;//要访问得磁道数cout〈〈” 输入得磁道序列为:”;ﻩfor(i=0;i〈count;i++)ﻩcout〈<cidao[i]〈<””;//输出磁道序列cout〈〈endl;ﻩwhile(1){cout<<endl;cout<<” —--——------————----——---—-—--——-———-—-------—--——--—-—---—-—---—------—-—”〈<endl;cout<〈"\n1、先来先服务2、最短寻道时间优先3、扫描调度4、循环扫描5、退出\n"〈<endl;ﻩﻩcout〈〈" —-—----——-—-——---—-——-——————-—--—-—-—-—--——----—--—-—--————-—-—---—————--"〈〈endl;G:cout<〈” 请选择算法:";F:cin>>str;//对输入数据进行有效性判断a=decide(str);ﻩﻩif(a==0){ﻩcout<〈” 输入数据得类型错误,请重新输入!"〈<endl;ﻩgotoF;//输入错误,跳转到F,重新输入ﻩ}ﻩelseﻩc=trans(str,a);ﻩif(c==5)ﻩbreak;ﻩif(c〉5){ﻩcout〈<" 输入得数据错误!请重新输入"<〈endl;goto G;}switch(c){ﻩcase 1: //使用FCFS算法ﻩﻩﻩﻩFCFS(cidao,count);ﻩﻩﻩbreak;ﻩcase2: //使用SSTF算法ﻩﻩSSTF(cidao,count);ﻩﻩbreak;ﻩﻩcase 3://使用SCAN算法ﻩSCAN(cidao,count);ﻩbreak;ﻩﻩcase 4: //使用CSCAN算法ﻩﻩCSCAN(cidao,count);ﻩﻩﻩﻩbreak;ﻩﻩ}ﻩ}}五、实验结果5、1 程序主界面运行程序后,将会提示用户输入磁道序列,并且以0结束。