操作系统课程设计磁盘调度算法.docx

上传人:b****6 文档编号:8605036 上传时间:2023-02-01 格式:DOCX 页数:30 大小:177.37KB
下载 相关 举报
操作系统课程设计磁盘调度算法.docx_第1页
第1页 / 共30页
操作系统课程设计磁盘调度算法.docx_第2页
第2页 / 共30页
操作系统课程设计磁盘调度算法.docx_第3页
第3页 / 共30页
操作系统课程设计磁盘调度算法.docx_第4页
第4页 / 共30页
操作系统课程设计磁盘调度算法.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

操作系统课程设计磁盘调度算法.docx

《操作系统课程设计磁盘调度算法.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计磁盘调度算法.docx(30页珍藏版)》请在冰豆网上搜索。

操作系统课程设计磁盘调度算法.docx

操作系统课程设计磁盘调度算法

《计算操作系统》

课程设计报告

 

 

姓名:

崔玲玲

班级:

软件111

学号:

201101014103

指导老师:

夏辉丽

目录

1.操作系统课程设计任务描述1

1.1先来先服务算法(FCFS)1

1.2最短寻道时间优先算法(SSTF)1

1.3扫描算法(SCAN)1

1.4循环扫描算法(CSCAN)1

2.问题定义与需求分析2

2.1输入的形式2

2.2输入值的范围2

2.3输出的形式2

2.4程序所能达到的功能2

2.5测试数据2

3.概要设计及流程图3

3.1子模块的调用关系3

3.2个别函数的参数3

3.3主要的流程图3

4.问题实现及代码5

4.1先来先服务算法的实现5

4.2最短寻道时间优先算法的实现6

4.3扫描算法的实现7

4.4循环扫描算法的实现7

5.调试分析9

6.测试9

6.1测试数据9

6.2测试界面10

7.课设总结12

8.参考文献13

9.源代码14

1.操作系统课程设计任务描述

本课程设计的目的是通过设计一个磁盘调度模拟系统,从而使磁盘调度算法更加形象化,容易使人理解,使磁盘调度的特点更简单明了,这里主要实现磁盘调度的四种算法,分别是先来先服务算法、最短寻道时间优先算法、扫描算法以及循环扫描算法等磁盘调度算法。

1.1先来先服务算法(FCFS)

这是一种比较简单的磁盘调度算法,它根据进程请求访问磁盘的先后次序进行调度。

此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。

1.2最短寻道时间优先算法(SSTF)

该算法要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,该算法可以得到比较好的吞吐量,但却不能保证平均寻道时间最短,对用户的服务请求的响应机会不是均等的。

1.3扫描算法(SCAN)

扫描算法不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头的当前移动方向。

例如,当磁头正在自里向外移动时,等请求到磁道的外部边缘时,磁道调换方向,开始从最小号磁道依次向最大号磁道服务。

这样很好的避免了饥饿现象的出现。

吞吐量较大,平均响应时间较小。

其缺点是对用户的服务请求的响应机会不是均等的,因而导致响应时间的变化幅度很大。

1.4循环扫描算法(CSCAN)

循环扫描算法是对扫描算法的改进,不同于循环扫描的是循环扫描算法规定磁头单向移动,也就是当磁头到达磁盘的边缘时,磁头则直接返回到磁盘的另一边缘,继续做原来请求方向进行服务。

此算法解决了扫描算法的缺点,也同时具有最短寻道时间优先算法的优点即吞吐量较大,平均响应时间较小不过,磁道两端的访问频率仍低于磁道中间的访问频率。

 

2.问题定义与需求分析

2.1输入的形式

磁道号数组的输入:

定义一个数组,intcidao[],先提示用户输入磁道号串的个数n,然后依次输入n个磁道号(磁道号中间可用空格或回车键隔开),输入完毕后回车键结束输入,运行下一步。

2.2输入值的范围

数据的大小:

全局变量maxsize=1000,磁道数组cidao[maxsize]的大小就是1000,输入时有大小提示,大于最大值时则也只能保存前1000个数据。

关于intnow,表示的是当前的磁道号,程序运行时会让用户在每种算法中都输入当前的磁道号now,如果输入了除数字以外的字符,则提示错误,让用户重新输入。

2.3输出的形式

用户输入磁道数组后,程序会显示用户输入的数组,按用户的输入顺序输出,输出形式是一横行,如果是排序之后的,则输出排序后的磁道号。

2.4程序所能达到的功能

程序的main函数实现了程序的运行模式,运行后首先会显示磁盘调度算法系统的系统名称,紧接着下面就是系统菜单,在系统菜单里,可以供用户选择6个选项:

1.输入磁道号2.先来先服务3.最短寻道时间优先4.扫描调度5.循环扫描6.退出系统,

由用户输入磁道号串后,可以连续选择不同的调度算法,不过每种调度算法都会提示用户重新输入当前的磁道号而不用再输入磁道号串,操作起来比较方便;在扫描和循环扫描算法中,还会让用户选择磁道的请求方向,向内还是向外;选择系统退出时,系统会提示是否真的退出(yes/no),如果手动输入大写的YES或是小写的yes系统都会退出,如果输入的是其他字符系统则调用main(),继续磁盘调度的算法操作。

2.5测试数据

由于定义的磁道数组和当前磁道号的数据类型都是整形数,所以用cin.fail()函数检验错误,如果有数据类型错误的错误,再用cin.clear()进行错误清除,接着再用一个cin.ignore()函数忽略掉输入的错误数据,最后用goto返回,继续进行数组数据的输入,这样可以有效的避免用户手误输错的情况。

3.概要设计及流程图

3.1子模块的调用关系

本程序主要分为八大模块,除了系统菜单里的六个选择项之外,还有排序函数paixu(),主函数mian()。

在主函数里,有用户选择输入,算法以及退出,用switch函数控制,去调用外部的函数FCFS(),SSTF(),SCAN(),CSCAN(),shuru()和Exit()分别进行算法实现。

其中用到排序的算法SSTF(),SCAN()和CSCAN()都在函数里调用了paixu()进行排序。

3.2个别函数的参数

四个算法函数和shuru()函数都用参数,像FCFS(intcidao[],intm),cidao[]是磁道数组,函数实现的时候函数里的参数可以不同于intcidao[],结果都是对的,因为其根本都是对主函数里的intcidao[maxsize]进行操作的;intm是指磁道号的个数,输入函数shuru()完成给m以及磁道号串的赋值,因为输入函数规定了磁道的大小和各个磁道号。

3.3主要的流程图

主函数主要是实现功能的选择,流程图如图1所示。

先来先服务函数的流程很简单,用户输入磁道号串后,选择菜单功能2即调用先来先服务磁盘调度算法,用户再输入当前磁道号,系统会显示磁盘寻求序列也就是磁道的输入顺序,然后依次给予服务,最后在求和,输出平均值,本设计报告省略了此算法的流程图。

最短寻道时间优先算法的实现不同于先来先服务算法,它需要调用排序函数来给磁道号排序,然后在服务,流程图如图2所示。

扫描算法的实现流程图如图3所示;循环扫描算法是基于扫描算法实现的,与之不同的是循环扫描算法当原来的磁头访问到磁到边缘后,磁头直接跳到磁盘的另一边缘,然后按原来的寻求方向继续给磁道服务,此处省略了流程图。

 

图1主函数流程图

图3.3.1

图2最短寻道时间优先算法流程图

图3扫描算法流程图

4.问题实现及代码

4.1先来先服务算法的实现

voidFCFS(intcidao[],intm),输入磁道号,按先来先服务的策略输出磁盘请求序列,求平均寻道长度,输出移动平均磁道数。

主要代码:

for(i=0,j=1;j

{

sum+=abs(array[j]-array[i]);

ave=(float)(sum)/(float)(m);

}

4.2最短寻道时间优先算法的实现

voidSSTF(intcidao[],intm),将磁道号用冒泡法从小到大排序,输出排好序的磁道序列,输入当前磁道号,根据前磁道在已排的序列中的位置,分三种情况进行访问总长度计算,第三种是比较找到离now最近的磁道号坐标,按找到的磁道号方向访问,然后反过来访问其他未访问的,算出寻道总长度,输出移动的平均磁道长度。

主要代码:

(1)当前磁道号大于请求序列中最大者时,直接从大到小依次给予各请求服务

if(cidao[m-1]<=now)

{

cout<<"磁盘扫描序列为:

";

for(i=m-1;i>=0;i--)

cout<

sum=now-cidao[0];

}

(2)当前磁道号小于请求序列中最小者时,直接从小到大依次给予各请求服务

if(cidao[0]>=now)

{

cout<<"磁盘扫描序列为:

";

for(i=0;i

cout<

sum=cidao[m-1]-now;

}

(3)当前磁道号大于请求序列中最小者且小于最大者时

while(cidao[k]

{

k++;//k为离now最近的磁道坐标

}

l=k-1;//l为now左边的磁道坐标

r=k;//r为now右边的磁道坐标

if((now-cidao[l])<=(cidao[r]-now))//选择与当前磁道最近的请求给予服务

{

cout<

sum+=now-cidao[l];

now=cidao[l];

l=l-1;

}

4.3扫描算法的实现

扫描算法的实现跟最短寻道时间算法很相像,不同之处在于扫描算法中要先确定当前磁道访问的方向,向外还是向内?

这由用户选择。

主要代码:

intd;

cout<<"请输入当前移动臂的移动的方向(1表示向内,0表示向外):

";

cin>>d;

if(d==0)//选择移动臂向磁道号减小的方向扫描

{

cout<<"磁盘扫描序列为:

";

for(j=l;j>=0;j--)

{

cout<

}

for(j=r;j

{

cout<

}

sum=now-cidao[0]+cidao[m-1]-cidao[0];

}

else//另一种磁道向磁道号增加的方向访问

4.4循环扫描算法的实现

循环扫描算法的难点在于磁道总长度的计算,这里只说当前磁道号大于请求序列中最小者且小于最大者时的情况,由d的不同分为两种计算,当d选择为向外扫描时,又分为两种计算,因为由于寻找离now最近的磁道号时,r=k,k所对应的的磁道号有可能等于now,为了避免计算错误分为两种计算方法,保证了代码的准确性。

if(d==0)//选择移动臂向磁道号减小的方向扫描

{

if(now==cidao[r])

{

for(j=r;j>=0;j--)

{

cout<

}

//当扫描完最小号磁道,磁头直接移动到最大号磁道从大到小依次给予未服务的磁道服务

for(j=m-1;j>r;j--)

{

cout<

}

sum+=now-cidao[0]+cidao[m-1]-cidao[0]+cidao[m-1]-cidao[r+1];

}

else

{

for(j=l;j>=0;j--)

{

cout<

}

//当扫描完最小号磁道,磁头直接移动到最大号磁道从大到小依次给予未服务的磁道服务

for(j=m-1;j>l;j--)

{

cout<

}

sum+=now-cidao[0]+cidao[m-1]-cidao[0]+cidao[m-1]-cidao[r];

}

}

 

5.调试分析

运行过程中,发现第一种先来先服务算法,当输入的磁道号只有一个的时候,计算的平均值出错,是随机数,经过缜密的考虑才发现,这种情况应该作为特殊情况来考虑,所以,我在总长度计算的代码中增加了一种特殊情况。

代码如下:

if(m==1)//m是磁道号的个数

{

ave=(float)(sum)/(float)m;

cout<<"平均寻道长度:

"<

}

在输入函数里,我想要获取输入函数里规定的磁道号个数n,想把n传到主函数里,供其他算法例如FCFS(cidao,m)中的m使用,经过老师帮我调试才完成了这一功能,解决办法是:

在输入函数里定义一个参数shuru(intcidao[]),把输入函数定义成int类型,returnn(这里的n也指磁道号个数),在主函数里,定义一个intm,再把switch函数里的输入函数赋值给m,m=shuru(cidao),这样就有效的解决了问题。

6.测试

6.1测试数据

测试数据:

305010206040

(1)先来先服务算法

当前磁道号:

30

平均寻道长度:

21.66

(2)最短寻道时间优先算法

①当前磁道号大于磁道序列中的最大的磁道号时

当前磁道号:

70

平均寻道长度:

10

②当前磁道号小于磁道序列中的最小的磁道号时

当前磁道号:

5

平均寻道长度:

9.16

③当前磁道号大于磁道序列中的最小的磁道号且小于最大磁道号时

当前磁道号:

35

平均寻道长度:

12.5

(3)扫描算法

①当前磁道号大于磁道序列中的最大的磁道号时

当前磁道号:

70

平均寻道长度:

10

②当前磁道号小于磁道序列中的最小的磁道号时

当前磁道号:

5

平均寻道长度:

9.16

③当前磁道号大于磁道序列中的最小的磁道号且小于最大磁道号(磁头向外)

当前磁道号:

35

平均寻道长度:

12.5

④当前磁道号大于磁道序列中的最小的磁道号且小于最大磁道号(磁头向内)

当前磁道号:

35

平均寻道长度:

12.5

(4)循环扫描算法

①当前磁道号大于磁道序列中的最大的磁道号时

当前磁道号:

70

平均寻道长度:

18.33

②当前磁道号小于磁道序列中的最小的磁道号时

当前磁道号:

5

平均寻道长度:

9.16

③当前磁道号大于磁道序列中的最小的磁道号且小于最大磁道号(磁头向外)

当前磁道号:

30

平均寻道长度:

15

④当前磁道号大于磁道序列中的最小的磁道号且小于最大磁道号(磁头向内)

当前磁道号:

30

平均寻道长度:

15

6.2测试界面

(1)系统界面,运行程序以后,直接显示系统界面,请用户选择功能,如图4所示:

图4主界面

(2)选择功能1,表示输入磁道号串,输入之前先控制磁道号的个数n,如

图5所示:

图5数据的输入

(3)如果用户输入信息错误,在输入当前磁道号时输入了字母h,系统会提示用户输入信息类型错误,并要求用户重新输入,如图6所示:

图6错误提示

(4)根据输入的磁道号串,选择功能3,调用最短寻道时间优先调度算法,算法自动调用排序函数给输入的磁道号排序,然后输入当前磁道号5,最后根据算法输出寻求序列,算出平均寻道时间,如图7所示:

图7最短寻道时间优先调度算法

(5)选择功能5,系统调用循环扫描调度算法,先排序,再输入当前磁道号,如果当前磁道号大于最大的磁道号或者小于最小的磁道号,算法则直接输出寻求序列;这里当前磁道号输入30,在最大磁道号和最小磁道号中间,则继续选择当前磁道移动方向,选择向外移动,结果如图8所示:

图8循环扫描调度算法

(6)功能选择6,选择是否退出系统,如果确定退出,则输入大写或小写y,输入其他任何数据则是确认退出,确认退出如图9所示:

图9退出系统

7.课设总结

本次的操作系统课程设计,老师共给了六大题目,我觉得我在擦盘调度这一块学习的还比较扎实,理论知识理解的也不错,所以,我就选择了磁盘调度算法的实现。

本程序没有实现对服务过的磁道进行记录,根据磁盘调度算法的思想,是需要实现这一功能的,这样才能有利于对新来的进程进行服务,不至于把程序写死,本算法简化了磁盘调度算法,只是简单地模拟了对现有磁道号串的请求服务。

磁盘调度算法总共分为四大算法,在算法思想上都有一一介绍她们各自的优缺点。

可是,理论知识理解的好并不代表算法就能很好的实现,因此,在算法实现的过程中感觉还是比较吃力的,算法的整体是用一个简单的数组进行数据定义的,每个被调用的不同的算法的函数里都含有两个参数,一个是intcidao[],一个是intm,难点在于要非常清楚的明白这两个参数是怎么样被赋值的?

它们之间的关系又是怎么样的?

起初我也搞不懂,根本不知道怎么去用代码表达,后来经过老师的细心讲解,我才知道磁道的个数可以直接用输入函数里的返回值进行赋值,这样修改过程序在结构上就没有什么问题了;除此之外的难点就是磁道长度的计算,他之所以难是因为它比较复杂,考虑到的情况非常之多,经过我不断的调试和错误的发现和改正,才终于写成了现在的比较完整的程序。

通过这次的课程,让我再一次认识到,我现在所掌握的关于程序实现的知识还非常之少,像程序中避免输入错误的所用到的函数,我在之前都没有见过,不过,这次的使用让我很熟练地知道了它的用法。

本程序没有用可视化界面实现,因为这方面内容我不了解,我想我以后会抽空学习的,因为毕竟对它比较感兴趣。

8.参考文献

[1]汤小丹,梁红兵,哲凤屏,汤子瀛.计算机操作系统[M].西安电子科技大学出版社.2007.194-196

[2]郑秋生.C++程序设计教程[M].电子工业出版社.2007

[3]严蔚敏.数据结构[M].清华大学出版社.2007

 

9.源代码

#include

#include

#include

#include

#include

#definemaxsize1000

main();

int*paixu(intcidao[],intm)//冒泡算法

{

inti,j,temp;

for(i=0;i

for(j=i+1;j

{

if(cidao[i]>cidao[j])

{

temp=cidao[i];

cidao[i]=cidao[j];

cidao[j]=temp;

}

}

cout<<"排序后的磁盘序列为:

";

for(i=0;i

{

cout<

}

cout<

returncidao;

}

//先来先服务调度算法

voidFCFS(intcidao[],intm)//磁道号数组,个数为m

{

intnow;//当前磁道号

intj,i;

intsum=0;//总寻道长度

floatave;//平均寻道长度

cout<<"你选择了先来先服务调度算法"<

cout<<"磁盘请求序列为:

";

for(i=0;i

{

cout<

}

cout<

cout<<"请输入当前的磁道号:

";

A:

cin>>now;

if(cin.fail())

{

cout<<"输入数据类型错误!

请重新输入:

"<

cin.clear();//清除以上错误

cin.ignore();//忽略刚才流中的字符

gotoA;

}

sum+=abs(cidao[0]-now);//sum=sum+|(第一个磁道号)-(当前磁道)|

cout<<"磁盘扫描序列为:

";

for(i=0;i

{

cout<

}

if(m==1)

{

ave=(float)(sum)/(float)m;

cout<<"平均寻道长度:

"<

}

else

{

for(i=0,j=1;j

{

sum+=abs(cidao[j]-cidao[i]);

ave=(float)(sum)/(float)(m);

}

cout<

cout<<"平均寻道长度:

"<

}

}

//最短寻道时间优先调度算法

voidSSTF(intcidao[],intm)

{

inti,j;

intnow,l,r;

intk=1,sum=0;

floatave;

cout<<"你选择了最短寻道时间优先调度算法:

"<

cidao=paixu(cidao,m);//调用冒泡排序算法排序

cout<<"请输入当前的磁道号:

";

B:

cin>>now;

if(cin.fail())

{

cout<<"输入数据类型错误!

请重新输入:

"<

cin.clear();//清除以上错误

cin.ignore();//忽略刚才流中的字符

gotoB;

}

//若当前磁道号大于请求序列中最大者,则直接从大到小依次给予各请求服务

if(cidao[m-1]<=now)

{

cout<<"磁盘扫描序列为:

";

for(i=m-1;i>=0;i--)

cout<

sum=now-cidao[0];//磁道总长度就等于now减去第一个磁道号

}

//若当前磁道号小于请求序列中最小者,则直接从小到大依次给予各请求服务

if(cidao[0]>=now)

{

cout<<"磁盘扫描序列为:

";

for(i=0;i

cout<

sum=cidao[m-1]-now;

}

//若当前磁道号大于请求序列中最小者且小于最大者

if(now<=cidao[m-1]&&now>=cidao[0])

{

cout<<"磁盘扫描序列为:

";

while(cidao[k]

{

k++;//k为离now最近的磁道坐标

}

l=k-1;//l为now左边的磁道坐标

r=k;//r为now右边的磁道坐标

while((l>=0)&&(r

{

//选择与当前磁道最近的请求给予服务

if((now-cidao[l])<=(cidao[r]-now))

{

cout<

sum+=now-cidao[l];

now=cidao[l];

l=l-1;

}

else

{

cout<

sum+=cidao[r]-now;

n

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 商业计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1