磁盘模拟调度系统实习报告.docx
《磁盘模拟调度系统实习报告.docx》由会员分享,可在线阅读,更多相关《磁盘模拟调度系统实习报告.docx(17页珍藏版)》请在冰豆网上搜索。
磁盘模拟调度系统实习报告
操作系统实习报告
题目:
磁盘模拟调度系统
院系:
信息科学与工程学院
日期:
2010-7-8
目录
1.设计目的-1-
2.设计内容-1-
3.开发环境-1-
4.分析设计-1-
4.1.实验原理-1-
4.2.程序结构-2-
4.3.数据结构-2-
4.4.程序流程图-2-
5.运行示例及结果分析-7-
6.心得与体会-9-
7.参考文献-10-
附录:
源程序清单-10-
磁盘调度管理
1.设计目的
加深对请求磁盘调度管理实现原理的理解,掌握磁盘调度算法。
同时让我们更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强动手能力。
2.设计内容
设计一个磁盘调度模拟程序,具体要求如下:
1.用户可以为程序指定初始需要访问序列;
2.实现最短寻道和电梯调度两种调度算法;
3.根据用户的选择输出实际的访问序列;
3.开发环境
windows环境,VC6.0平台。
4.分析设计
4.1.实验原理
操作系统中,对磁盘的访问要求来自多方面,常常需要排队。
这时,对众多的访问要求按一定的次序响应,会直接影响磁盘的工作效率,进而影响系统的性能。
访问磁盘的时间因子由3部分构成,它们是查找(查找磁道)时间、等待(旋转等待扇区)时间和数据传输时间,其中查找时间是决定因素。
因此,磁盘调度算法先考虑优化查找策略,需要时再优化旋转等待策略。
平均寻道长度(L)为所有磁道所需移动距离之和除以总的所需访问的磁道数(n),即:
L=(M1+M2+……+Mi+……+Mn)/n
其中Mi为所需访问的磁道号所需移动的磁道数。
启动磁盘执行输入输出操作时,要把移动臂移动到指定的柱面,再等待指定扇区的旋转到磁头位置下,然后让指定的磁头进行读写,完成信息传送。
因此,执行一次输入输出所花的时间有:
寻找时间——磁头在移动臂带动下移动到指定柱面所花的时间。
延迟时间——指定扇区旋转到磁头下所需的时间。
传送时间——由磁头进程读写完成信息传送的时间。
其中传送信息所花的时间,是在硬件设计就固定的。
而寻找时间和延迟时间是与信息在磁盘上的位置有关。
为了减少移动臂进行移动花费的时间,每个文件的信息不是按盘面上的磁道顺序存放满一个盘面后,再放到下一个盘面上。
而是按柱面存放,同一柱面上的各磁道被放满信息后,再放到下一个柱面上。
所以各磁盘的编号按柱面顺序(从0号柱面开始),每个柱面按磁道顺序,每个磁道又按扇区顺序进行排序。
磁盘是可供多个进程共享的设备,当有多个进程都要求访问磁盘是,应采用一种最佳调度算法,以使各种进程对磁盘的平均访问时间最小。
由于在访问磁盘的时间中,主要是寻道时间,因此,磁盘调度的目标,是使磁盘的平均寻道时间最少。
这次磁盘调度模拟系统设计包含了四种算法,除了实验要求的最短寻道和电梯调度两种调度算法外,我还加进了先来先服务算法和循环扫描算法。
则这四种算法各自的原理如下:
先来先服务算法(First-Come,First-Served,FCFS):
这种算法最简单,它根据进程请求访问磁盘的先后次序进行调度。
此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。
但此算法由于未对寻道进行优化,致使平均寻道时间可能较长。
最短寻道时间优先算法(ShortestSeekTimeFirst,SSTF):
该算法选择这样的磁道来优先访问,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,但这种调度算法却不能保证平均寻道时间最短。
单向扫描算法(SCAN):
SCAN算法不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头的当前移动方向。
例如,当磁头正在自里向外移动时,SCAN算法所选择的下一个访问对象应是其欲访问的磁道既在当前磁道之外,又是距离最近的。
这样自里向外地访问,直到再无更外的磁道需要访问才将磁臂换向,自外向里移动。
这时,同样也是每次选择这样的进程来调度,即其要访问的磁道,在当前磁道之内,从而避免了饥饿现象的出现。
由于这种算法中磁头移动的规律颇似电梯的运行,故又称为电梯调度算法。
循环扫描算法(CSCAN):
这种算法是为了解决某个要访问的磁道(此磁道一般处于处于两个极端:
即最外和最里。
具体要根据磁头移动方向而定)的请求被严重地推迟。
为了减少这种延迟,CSCAN算法规定磁头单向移动。
例如,只自里向外移动,当磁头移到最外的被访问磁道时,磁头立即返回到最里的欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描。
4.2.程序结构
本程序主要包括五部分:
即一个主函数,以及四种算法各一个子函数。
程序中各子函数相对独立,其算法的实现主要是在主函数中对它们的调用来完成的。
在主函数里,首先先定义一个数组,用以存放要访问的所有磁道号信息;定义一个int型变量,用来存储需要访问的磁道的数量;定义一个int型变量,用来保存当前磁头所处的磁道号。
接下来就是对原始数据的输入,主要包括当前磁头所处的磁道号、需要访问的磁道的数量和要访问的所有磁道号信息。
再下来使用一个while循环实现对各算法的调用,在循环里,先要建立一个选择菜单,以方便用户使用。
后面再使用switch语句,并在其各子项中完成对各算法调用。
4.3.数据结构
intmin用于存储单步最短距离
intfirst磁头当前位置
intnum,n寻道次数
boolflag[maxsize]用于标志各磁道的状态(true/false)(访问/未访问)
intarray[],a[]用来存放要访问的所有磁道的磁道号
intsign用以保存b[]中和当前位置最近且磁道号大于等于当前位置的数组项的下标;
4.4.程序流程图
主函数程序流程图:
先来先服务算法程序流程图(array[],num,first分别为磁头当前位置、要访问的磁道的数量和要访问的所有磁道的磁道号):
最短寻道时间优先算法程序流程图(array[],num,first分别为磁头当前位置、要访问的磁道的数量和要访问的所有磁道的磁道号):
单向扫描算法程序流程图(array[],num,first分别为磁头当前位置、要访问的磁道的数量和要访问的所有磁道的磁道号):
循环扫描算法程序流程图(array[],num,first分别为磁头当前位置、要访问的磁道的数量和要访问的所有磁道的磁道号):
5.运行示例及结果分析
初始数据输入:
先来先服务算法:
分析:
这种算法最简单,其访问顺序和原始输入顺序一致。
由运行结果可知:
此算法由于未对寻道进行优化,致使平均寻道时间可能较长。
寻道最短时间优先算法:
分析:
这种算法相对复杂。
寻道最短时间优先算法总是从等待访问者中挑选寻找时间最短的那个请求先执行的,而不管访问者到来的先后次序。
单向扫描算法:
分析:
SCAN算法是磁头前进方向上的最短查找时间优先算法,它排除了磁头在盘面局部位置上的往复移动,SCAN算法在很大程度上消除了SSTF算法的不公平性,但仍只是有利于对中间磁道的请求,两端的磁道仍然有可能出现饥饿现象。
循环扫描算法:
分析:
CSCAN算法中,当磁头移到最外的被访问磁道时,磁头立即返回到最里的欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描,这种算法可以有效解决两端的磁道仍然有可能出现饥饿现象的问题。
6.心得与体会
至此,计算机操作系统实习已经完成。
课本上的知识是机械的,表面的。
此次的实习,使我对于磁盘调度算法和原理有了更深刻的理解。
对于理论在实践中的应用也有一定的了解。
通过这次课程设计,全面系统的理解了磁盘调度算法的一般原理和基本实现方法。
把死板的课本知识变得生动有趣,激发了学习的积极性。
虽然内容并不是很复杂,程序也不够完善和严谨,但是我们觉得设计的过程是相当重要的,从中我学到了很多,收获了很多,无论在理论上还是实践中,都得到不少的提高,这对于我以后的工作和学习都有一种巨大的帮助。
我觉得实习反映的是一个从理论到实际应用的过程,但是更远一点可以联系到以后毕业之后从学校转到踏上社会的一个过程。
我觉得作为一名计算机专业的学生,这次实习是很有意义的。
在这次设计中遇到了很多实际性的问题,在实际设计中才发现,书本上理论性的东西与在实际运用中的还是有一定的出入的,所以有些问题不但要深入地理解,而且要不断地更正以前的错误思维。
一切问题必须要靠自己一点一滴的解决,而在解决的过程当中你会发现自己在飞速的提升。
7.参考文献
[1].汤子瀛,哲凤屏,汤小丹编著.计算机操作系统.西安电子科技大学出版社,2005
[2].谭浩强编著.C语言程序设计(第3版).清华大学出版社,2005
附录:
源程序清单
#include"iostream.h"
#include"stdio.h"
#include"math.h"
#definemaxsize100
voidFcfs(intarray[],intnum,intfirst);//函数声明
voidSstf(intarray[],intnum,intfirst);
voidScan(intarray[],intnum,intfirst);
voidCscan(intarray[],intnum,intfirst);
voidmain()
{
inta[maxsize];//建一个数组,用来存放要访问的所有磁道
intc,n,first;
cout<<"/********************************************/"<cout<<"/欢迎使用磁盘调度模拟系统/"<cout<<"/********************************************/"<cout<<"请输入寻道的次数:
";
cin>>n;
cout<<"输入磁头当前位置:
";
cin>>first;
cout<<"输入要访问的所有磁道:
\n";
for(inti=0;i{
cin>>a[i];
}
while
(1)
{
cout<<"/********************************************/"<cout<<"/磁盘调度模拟系统菜单/"<cout<<"/********************************************/"<cout<<"/*1.先来先服务*/"<cout<<"/*2.最短寻道时间优先*/"<cout<<"/*3.单向扫描(电梯调度)*/"<cout<<"/*4.循环扫描*/"<cout<<"/*5.退出*/"<cout<<"/********************************************/"<cout<<"请选择:
";
cin>>c;
cout<if(c==5)//如果选择“5”,直接退出
break;
switch(c)
{
case1:
cout<<"先来先服务算法的结果:
\n"<<"下一个访问的磁道"<<"移动距离\n";
Fcfs(a,n,first);
break;
case2:
cout<<"\n最短寻道时间优先算法结果:
\n"<<"下一个访问的磁道"<<"移动距离\n";
Sstf(a,n,first);
break;
case3:
cout<<"\n扫描算法的结果:
\n"<<"下一个访问的磁道"<<"移动距离\n";
Scan(a,n,first);
break;
case4:
cout<<"\n循环扫描算法的结果:
\n"<<"下一个访问的磁道"<<"移动距离\n";
Cscan(a,n,first);
break;
}
}
}
voidFcfs(intarray[],intnum,intfirst)/*先来先服务*/
{
intb[maxsize];
intsum=0;//总移动距离
inttemp;
for(intk=0;k{
cout<temp=array[k];
b[k]=abs(array[k]-first);//移动距离
cout<
first=temp;//移动到下个磁道
}
for(intj=0;j{
sum+=b[j];//总移动距离
}
cout<<"\n总寻道长度为:
"<cout<<"\n平均寻道长度为:
"<}
voidSstf(intarray[],intnum,intfirst)/*最短寻道时间优先*/
{
intsum=0;
inttemp=first;
intb[maxsize];//定义一个数组,按访问顺序存放各磁道
intnumber=0;
boolflag[maxsize];//定义一个状态数组,用来指示磁道是否被访问,下标对应array[]数组
intmin;//设置一个变量,用来存放最短距离(离磁头距离最近且还未被访问的磁道和当前位置的距离)
intk,i;
min=abs(array[0]-first);
intj=0;
for(i=0;i{
flag[i]=false;
}
while(number{
for(k=0;k{
if(flag[k]==false)
{
min=abs(array[k]-first);
j=k;break;
}
}
for(i=0;i{
if(flag[i]==false&&min>abs(array[i]-first))
{
min=abs(array[i]-first);
j=i;
}
}
b[number]=array[j];
number++;
first=array[j];//设为当前位置
flag[j]=true;//磁道被访问后,flag置为true
}
for(k=0;k{
first=temp;//first回复初始状态
cout<
temp=b[k];
b[k]=abs(b[k]-first);
sum+=b[k];
cout<
}
cout<<"\n总寻道长度为:
"<cout<<"\n平均寻道长度:
"<}
voidScan(intarray[],intnum,intfirst)/*扫描(电梯)*/
{
intb[maxsize];
intsum=0;
inttemp,i,j,k;
intsign=num;
for(i=0;i{
b[i]=array[i];//复制数组
}
for(i=1;i{
for(j=0;j{
if(b[j]>b[j+1])
{
temp=b[j];
b[j]=b[j+1];
b[j+1]=temp;
}
}
}
for(i=0;i{
if(b[i]>=first){sign=i;break;}
}
for(j=sign;j{
cout<
cout<sum+=abs(b[j]-first);
first=b[j];//设为当前位置
}
for(k=sign-1;k>=0;k--)//依次访问b[]下标从sign-1到0几个磁道,同时依次输出磁道号和单步移动距离
{
cout<
cout<sum+=abs(b[k]-first);
first=b[k];//设为当前位置
}
cout<<"\n总寻道长度为:
"<cout<<"\n平均寻道长度:
"<}
voidCscan(intarray[],intnum,intfirst)/*循环扫描*/
{
intb[maxsize];
intsum=0;
inttemp,i,j,k;
intsign=num;
for(i=0;i{
b[i]=array[i];
}
for(i=1;i{
for(j=0;j{
if(b[j]>b[j+1])
{
temp=b[j];
b[j]=b[j+1];
b[j+1]=temp;
}
}
}
for(i=0;i{
if(b[i]>=first){sign=i;break;}//确定标志sign的位置
}
for(j=sign;j{
cout<
cout<sum+=abs(b[j]-first);
first=b[j];//设为当前位置
}
for(k=0;k{
cout<
cout<sum+=abs(b[k]-first);
first=b[k];//设为当前位置
}
cout<<"\n总寻道长度为:
"<cout<<"\n平均寻道长度:
"<}