操作系统磁盘调度算法.docx
《操作系统磁盘调度算法.docx》由会员分享,可在线阅读,更多相关《操作系统磁盘调度算法.docx(15页珍藏版)》请在冰豆网上搜索。
操作系统磁盘调度算法
操作系统课程设计任务书
题目:
磁盘调度算法
院系:
专业:
班级:
姓名:
学号:
指导教师:
设计时间:
指 导 教 师 评 语
成绩评定:
指导教师签字:
年 月 日
1、需求分析4
课题描述4
课题目的4
理论依据7
2、概要设计8
设计方法8
技术8
运行环境8
3、详细设计9
流程图11
程序主要代码13
4、运行结果及分析14
运行结果15
结果详细分析16
5、总结和心得16
6、参考文献17
7、附录:
程序源代码23
1、需求分析
课题描述
这次课程设计我研究的题目是:
磁盘调度算法。
具体包括三种算法分别是:
先来先服务算法(FCFS)、最短寻道时间优先算法(SSTF)、扫描算法(电梯调度算法)(SCAN)。
课题目的
通过这次实验,加深对磁盘调度算法的理解,进一步掌握先来先服务FCFS,最短寻道时间优先SSTF,扫描SCAN算法的实现方法。
理论依据
设备的动态分配算法与进程调度相似,也是基于一定的分配策略的。
常用的分配策略有先请求先分配、优先级高者先分配等策略。
在多道程序系统中,低效率通常是由于磁盘类旋转设备使用不当造成的。
操作系统中,对磁盘的访问要求来自多方面,常常需要排队。
这时,对众多的访问要求按一定的次序响应,会直接影响磁盘的工作效率,进而影响系统的性能。
访问磁盘的时间因子由3部分构成,它们是查找(查找磁道)时间、等待(旋转等待扇区)时间和数据传输时间,其中查找时间是决定因素。
因此,磁盘调度算法先考虑优化查找策略,需要时再优化旋转等待策略。
平均寻道长度(L)为所有磁道所需移动距离之和除以总的所需访问的磁道数(N),即:
L=(M1+M2+?
?
+Mi+?
?
+MN)/N
其中Mi为所需访问的磁道号所需移动的磁道数。
启动磁盘执行输入输出操作时,要把移动臂移动到指定的柱面,再等待指定扇区的旋转到磁头位置下,然后让指定的磁头进行读写,完成信息传送。
因此,执行一次输入输出所花的时间有:
寻找时间——磁头在移动臂带动下移动到指定柱面所花的时间。
延迟时间——指定扇区旋转到磁头下所需的时间。
传送时间——由磁头进程读写完成信息传送的时间。
其中传送信息所花的时间,是在硬件设计就固定的。
而寻找时间和延迟时间是与信息在磁盘上的位置有关。
为了减少移动臂进行移动花费的时间,每个文件的信息不是按盘面上的磁道顺序存放满一个盘面后,再放到下一个盘面上。
而是按柱面存放,同一柱面上的各磁道被放满信息后,再放到下一个柱面上。
所以各磁盘的编号按柱面顺序,每个柱面按磁道顺序,每个磁道又按扇区顺序进行排序。
磁盘是可供多个进程共享的设备,当有多个进程都要求访问磁盘是,应采用一种最佳调度算法,以使各种进程对磁盘的平均访问时间最小。
由于在访问磁盘的时间中,主要是寻道时间,因此,磁盘调度的目标,是使磁盘的平均寻道时间最少。
目前常用的磁盘帝调度算法有:
先来先服务、最短寻道时间优先及扫描等算法。
先来先服务(FCFS)调度:
按先来后到次序服务,未作优化。
最简单的移臂调度算法是“先来先服务”调度算法,这个算法实际上不考虑访问者要求访问的物理位置,而只是考虑访问者提出访问请求的先后次序。
例如,如果现在读写磁头正在50号柱面上执行输出操作,而等待访问者依次要访问的柱面为130、199、32、159、15、148、61、99,那么,当50号柱面上的操作结束后,移动臂将按请求的先后次序先移到130号柱面,最后到达99号柱面。
采用先来先服务算法决定等待访问者执行输入输出操作的次序时,移动臂来回地移动。
先来先服务算法花费的寻找时间较长,所以执行输入输出操作的总时间也很长。
最短寻找时间优先调度算法总是从等待访问者中挑选寻找时间最短的那个请求先执行的,而不管访问者到来的先后次序。
现在仍利用同一个例子来讨论,现在当50号柱面的操作结束后,应该先处理61号柱面的请求,然后到达32号柱面执行操作,随后处理15号柱面请求,后继操作的次序应该是99、130、148、159、199。
采用最短寻找时间优先算法决定等待访问者执行操作的次序时,读写磁头总共移动了200多个柱面的距离,与先来先服务、算法比较,大幅度地减少了寻找时间,因而缩短了为各访问者请求服务的平均时间,也就提高了系统效率。
但最短查找时间优先(SSTF)调度,FCFS会引起读写头在盘面上的大范围移动,SSTF查找距离磁头最短(也就是查找时间最短)的请求作为下一次服务的对象。
SSTF查找模式有高度局部化的倾向,会推迟一些请求的服务,甚至引起无限拖延(又称饥饿)。
SCAN算法又称电梯调度算法。
SCAN算法是磁头前进方向上的最短查找时间优先算法,它排除了磁头在盘面局部位置上的往复移动,SCAN算法在很大程度上消除了SSTF算法的不公平性,但仍有利于对中间磁道的请求。
“电梯调度”算法是从移动臂当前位置开始沿着臂的移动方向去选择离当前移动臂最近的那个柱访问者,如果沿臂的移动方向无请求访问时,就改变臂的移动方向再选择。
这好比乘电梯,如果电梯已向上运动到4层时,依次有3位乘客陈生、伍生、张生在等候乘电梯。
他们的要求是:
陈生在2层等待去10层;伍生在5层等待去底层;张生在8层等待15层。
由于电梯目前运动方向是向上,所以电梯的形成是先把乘客张生从8层带到15层,然后电梯换成下行方向,把乘客伍生从5层带到底层,电梯最后再调换方向,把乘客陈生从2层送到10层。
但是,“电梯调度”算法在实现时,不仅要记住读写磁头的当前位置,还必须记住移动臂的当前前进方向。
2、概要设计
设计方法
通过C语言的编程,设计程序模拟先来先服务FCFS,最短寻道时间优先SSTF,和扫描SCAN算法的工作过程。
假设有n个磁道号所组成的磁道访问序列,给定开始磁道号m和磁头移动的方向(正向或者反向),分别利用不同的磁盘调度算法访问磁道序列,给出磁头每一次移动的过程,算出磁头移动的距离,继而计算每种算法的平均寻道长度。
技术
C语言、操作系统磁盘调度算法、C++。
运行环境
Window10、VC++。
3、详细设计
流程图
先来先服务算法(FCFS):
最短寻道时间优先算法(SSTF):
扫描SCAN算法:
程序主要代码
先来先服务算法(FCFS):
voidFCFS(vectorm_vec,intposition){汤子瀛,哲凤屏,汤小丹.《计算机操作系统》.西安电子科技大学出版社,2005;
[2].谭浩强编着.《C语言程序设计(第3版)》.清华大学出版社,2005;
[3].吴乃陵,况迎辉.《C++程序设计(第二版)》.高等教育出版社,2005。
7、附录:
程序源代码
FCFS:
#include
#include<>
#include
#include
#include<>
#include<>
#include
#include<>
#include
usingnamespacestd;
intposition=0;//当前磁道位置
intdis=0;
doubleaverage_distance=0;
voidrequest(vector&m_vec,ofstream&outfile){
cout<<"随机生成磁盘序列:
"<intn=0;
srand(time(NULL));//添加随机数种子
n=rand()%20+1;
inttemp=0;
for(inti=0;itemp=rand()%100;
(temp);
cout<outfile<}
cout<position=rand()%100;
cout<<"当前磁道:
"<}
voidcompute_dis(vectorm_vec,int&dis,double&average_distance){
average_distance=(double)dis/(double)();
}
voidFCFS(vectorm_vec,intposition){//先来先服务算法
dis=0;
average_distance=0;
for(vector:
:
iteratorit=();it!
=();it++){
dis+=abs(position-*it);
Sleep(500);
cout<<"->"<<*it;
position=*it;
}
compute_dis(m_vec,dis,average_distance);
}
voidprint(){
cout<cout<<"经计算,磁头移动的总距离为:
"<cout<<"磁头平均移动距离:
"<cout<}
intmain(){
ofstreamoutfile;
("");
vectorm_vec;
request(m_vec,outfile);//请求服务序列
cout<<"磁盘请求的服务状况:
"<FCFS(m_vec,position);
print();
();
return0;
}
SSTF:
#include
#include<>
#include
#include<>
#include<>
#include
#include
#include<>
#include
usingnamespacestd;
intposition=0;//当前磁道位置
intdis=0;
doubleaverage_distance=0;
voidrequest(vector&m_vec,ofstream&outfile){
cout<<"随机生成磁盘序列:
"<intn=0;
srand(time(NULL));//添加随机数种子
n=rand()%20+1;
inttemp=0;
for(inti=0;itemp=rand()%100;
(temp);
cout<outfile<}
cout<position=rand()%100;
cout<<"当前磁道:
"<}
voidcompute_dis(vectorm_vec,int&dis,double&average_distance){
average_distance=(double)dis/(double)();
}
voidSSTF(vectorm_vec,intposition){//最短寻道时间算法
dis=0;
average_distance=0;
sort(),());//从小到大排序
inti=0;
for(vector:
:
iteratorit=();it!
=();it++){
if(position>=*it)
i++;
}
intcount=0;
intleft=i-1;
intright=i;
while(count<()){
if((left>=0&&abs(m_vec[right]-position)>abs(m_vec[left]-position))||right>=()){
dis+=abs(m_vec[left]-position);
Sleep(500);
cout<<"->"<position=m_vec[left];
left--;
}
else{
dis+=abs(m_vec[right]-position);
Sleep(500);
cout<<"->"<position=m_vec[right];
right++;
}
count++;
}
compute_dis(m_vec,dis,average_distance);
}
voidprint(){
cout<cout<<"经计算,磁头移动的总距离为:
"<cout<<"磁头平均移动距离:
"<cout<}
intmain(){
ofstreamoutfile;
("");
vectorm_vec;
request(m_vec,outfile);//请求服务序列
cout<<"磁盘请求的服务状况:
"<SSTF(m_vec,position);
print();
();
return0;
}
SCAN:
#include
#include<>
#include
#include<>
#include<>
#include
#include
#include<>
#include
usingnamespacestd;
intposition=0;//当前磁道位置
intdis=0;
doubleaverage_distance=0;
voidrequest(vector&m_vec,ofstream&outfile){
cout<<"随机生成磁盘序列:
"<intn=0;
srand(time(NULL));//添加随机数种子
n=rand()%20+1;
inttemp=0;
for(inti=0;itemp=rand()%100;
(temp);
cout<outfile<}
cout<position=rand()%100;
cout<<"当前磁道:
"<}
voidcompute_dis(vectorm_vec,int&dis,double&average_distance){
average_distance=(double)dis/(double)();
}
voidSCAN(vectorm_vec,intposition){//电梯调度算法
dis=0;
average_distance=0;
sort(),());//从小到大排序
inti=0;
for(vector:
:
iteratorit=();it!
=();it++){
if(position>=*it)
i++;//找到position所在的磁道
}
intleft=i-1;//先从外到内扫描
intright=i;
while(left>=0){
dis+=abs(position-m_vec[left]);
Sleep(500);
cout<<"->"<position=m_vec[left];
left--;
}
while(right<()){
dis+=abs(position-m_vec[right]);
Sleep(500);
cout<<"->"<position=m_vec[right];
right++;
}
compute_dis(m_vec,dis,average_distance);
}
voidprint(){
cout<cout<<"经计算,磁头移动的总距离为:
"<cout<<"磁头平均移动距离:
"<cout<}
intmain(){
ofstreamoutfile;
("");
vectorm_vec;
request(m_vec,outfile);//请求服务序列
cout<<"磁盘请求的服务状况:
"<SCAN(m_vec,position);
print();
();
return0;
}