操作系统课程设计报告磁盘调度算法.docx
《操作系统课程设计报告磁盘调度算法.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告磁盘调度算法.docx(24页珍藏版)》请在冰豆网上搜索。
操作系统课程设计报告磁盘调度算法
课程设计报告
(本科)
课程:
计算机操作系统
学号:
姓名:
班级:
计算机科学与技术(2010网络工程)
教师:
时间:
2012.12.17-2013.1.7
计算机科学与技术系
设计名称:
磁盘调度算法
设计内容、目的与要求:
一:
课程设计目的
使学生熟悉磁盘管理系统的设计方法;加深对所学各种磁盘调度算法的了解及其算法的特点。
二:
具体要求:
编程序实现下述磁盘调度算法,并求出每种算法的平均寻道长度:
1、先来先服务算法(FCFS)
2、最短寻道时间优先算法(SSTF)
3、扫描算法(SCAN)
4、循环扫描算法(CSCAN)
三:
课程设计内容
1.系统分析
选择一个自己熟悉的计算机系统和程序设计语言模拟操作系统基本功能的设计方法及其实现过程
完成各分项功能。
在算法的实现过程中,要求可决定变量应是动态可变的;同时模块应该有一个合理的输出结果。
具体可参照实验的程序模拟.各功能程序要求自行编写程序实现,不得调用现有操作系统提供的模块或功能函数。
磁盘调度程序模拟。
先来先服务调度算法,最短寻道时间优先调度,循环(SCAN)调度算法。
程序设计语言自选,最终以软件(含源代码以及执行程序)和设计报告的形式提交课程设计结果。
磁盘调度让有限的资源发挥更大的作用
2.磁盘调度
在多道程序设计的计算机系统中,各个进程可能会不断提出不同的对磁盘进行读/写操作的请求。
由于有时候这些进程的发送请求的速度比磁盘响应的还要快,因此我们有必要为每个磁盘设备建立一个等待队列。
①先来先服务(FCFS:
first-come-first-served)的策略,即先来的请求先被响应。
FCFS策略看起来似乎是相当"公平"的,但是当请求的频率过高的时候FCFS策略的响应时间就会大大延长。
FCFS策略为我们建立起一个随机访问机制的模型,但是假如用这个策略反复响应从里到外的请求,那么将会消耗大量的时间。
为了尽量降低寻道时间,看来我们需要对等待着的请求进行适当的排序,而不是简单的使用FCFS策略。
这个过程就叫做磁盘调度管理。
有时候fcfs也被看作是最简单的磁盘调度算法。
②最短时间优先算法选择这样的进程。
要求访问的磁道,与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。
③扫描(SCAN)调度算法:
该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。
例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道,既在当前磁道之外,又是距离最近的。
这样自里向外的访问,直至再无更外的磁道需要访问时,才将磁道换向自外向里移动。
这时,同样也是每次选择这样的进程来调度,也就是要访问的当前位置内距离最近者,这样,磁头又逐步地从外向里移动,直至再无更里面的磁道要访问,从而避免了出现“饥饿”现像。
④循环扫描(CSCAN)算法:
当磁头刚从里向外移动而越过了某一磁道时,恰好又有一进程请求访问此磁道,这时,该里程就必须等待,为了减少这种延迟,CSCAN算法规定磁头单向移动,而本实验过程中我们所设计的是磁头从里向外移动,而从外向里移动时只须改方向而已,本实验未实现。
但本实验已完全能演示循环扫描的全过程。
计划与进度安排:
2012-12-17至2012-12-23数据结构设计
设计中用到如下数据结构:
Hand:
当前磁道号;
DiscLine[10]:
随机生成的磁道号;
voidSetDI(intDiscL[])生成随机磁道号算法;
voidCopyL(intSour[],intDist[],intx)数组Sour复制到数组Dist,复制到x个数;
voidDelInq(intSour[],intx,inty)数组Sour把x位置的数删除,x后的数组元素向前挪一位;
voidPaiXu()寻道长度由低到高排序;
voidFCFS(intHan,intDiscL[])先来先服务算法(FCFS);
voidSSTF(intHan,intDiscL[])最短寻道时间优先算法(SSTF);
intSCAN(intHan,intDiscL[],intx,inty)扫描算法(SCAN);
voidCSCAN(intHan,intDiscL[])循环扫描算法(CSCAN);
2012-12-24至2013-1-1编写代码:
编写主函数的相关功能,如显示相关操作框架;然后针对主函数里需要调用的函数进行编写,函数算法有:
先来先服务算法、最短寻道优先算法、扫描算法、循环扫描算法、随机生成磁道数算法、排序算法以及四大调度算法中需要用到的复制数组算法和数组内部交换数值算法等;
2013-1-2至2013-1-6调试运行:
把各算法同主函数进行整合,调试运行,从具体运行实际上发现你需要改进的功能及不足,然后对其进行改进;
2013-1-6至2013-1-7得出最终程序和可执行文件,最后撰写实验报告。
设计过程、步骤(可加页):
一:
小组分工
1.徐洋:
小组组长,负责主函数设计、先来先服务算法;
2.武子良:
负责最短寻道时间优先算法;
3.金斌:
负责扫描算法;
4.陶加平:
负责循环扫描算法;
5.代码最终整理整合、课程设计报告整理:
小组共同完成。
二:
程序设计流程图或N-S图
1.系统流程图:
2.先来先服务(FCFS):
这是一种简单的磁盘调度算法。
它根据进程请求访问磁盘的先后次序进行调度。
此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。
但此算法由于未对寻道进行优化,致使平均寻道时间可能较长。
先来先服务算法(FCFS)流程图:
3.最短寻道时间优先(SSTF):
该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,但这种调度算法却不能保证平均寻道时间最短。
最短寻道时间优先(SSTF)流程图:
4.扫描算法(SCAN):
SCAN算法不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头的当前移动方向。
例如,当磁头正在自里向外移动时,SCAN算法所选择的下一个访问对象应是其欲访问的磁道既在当前磁道之外,又是距离最近的。
这样自里向外地访问,直到再无更外的磁道需要访问才将磁臂换向,自外向里移动。
这时,同样也是每次选择这样的进程来调度,即其要访问的磁道,在当前磁道之内,从而避免了饥饿现象的出现。
由于这种算法中磁头移动的规律颇似电梯的运行,故又称为电梯调度算法。
扫描算法(SCAN)流程图:
5.循环扫描(CSCAN)算法:
处理该进程的请求,致使该进程的请求被严重地推迟。
为了减少这种延迟,CSCAN算法规定磁头单向移动。
例如,只自里向外移动,当磁头移到最外的被访问磁道时,磁头立即返回到最里的欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描。
循环扫描算法(CSCAN)流程图:
结果与分析(可以加页):
功能模块(或算法)描述
1.先来先服务调度(FCFS)
输入起始磁道(你可以输入100),点确定,进入第二个界面,再输入你要输入的最大磁道(你可以输入50),然后点确定。
选择磁盘调度算法1234中的任意一个,若选择1后确认,则随机输出10个小于50的磁道数(411734019242881214),则先来先服务调度(FCFS)输出:
(411734019242881214),在选择1或者0,选择1则继续其它算法的磁盘调度,选择0则结束磁盘调度。
运行结果图:
2.最短寻道时间优先调度(SSTF)
输入起始磁道(你可以输入100),点确定,进入第二个界面,再输入你要输入的最大磁道(你可以输入50),然后点确定。
选择磁盘调度算法1234中的任意一个,若选择2后确认,则随机输出10个小于50的磁道数 (5453127114145422736),则最短寻道时间优先调度(SSTF):
(454542413631272711)。
在选择1或者0,选着1则继续其它算法的磁盘调度,选着0则结束磁盘调度。
运行结果图:
3.扫描调度算法(SCAN)
输入起始磁道(你可以输入100),点确定,进入第二个界面,再输入你要输入的最大磁道(你可以输入50),然后点确定。
选择磁盘调度算法1234中的任意一个,若选择3后确认,则随机输出10个小于50的磁道数 :
(41423423221161845),则扫描调度算法(SCAN):
(45424132211816432)。
在选择1或者0,选着1则继续其它算法的磁盘调度,选着0则结束磁盘调度。
运行结果图:
4.循环扫描算法(CSCAN)
输入起始磁道(你可以输入100),点确定,进入第二个界面,再输入你要输入的最大磁道(你可以输入50),然后点确定。
选择磁盘调度算法1234中的任意一个,若选择4后确认,则随机输出10个小于50的磁道数 :
(47262138191217493544),则循环扫描算法(CSCAN):
(12171921263538444749)。
运行结果图:
设计体会与建议:
至此,计算机操作系统课程设计算法已经完成。
此次设计基本完成了所规定的功能,但由于这次设计的时间比较仓促,其中不免会有些纰漏,比如在程序的实现上还不够严谨,出错处理不够完善等多方面问题,这些都有进一步改善。
由于平时上课不是很认真许多概念没有理解清楚,导致在做设计时有点无从下手的感觉,只好边实验边看书直到弄懂概念后才开始做设计导致时间有点紧张,最终在同学和老师的指导下我完成了设计,此设计基本能够实现规定的要求但是还是不够完善,很多东西做的不够好,程序不够完善和严谨。
此次课程设计中我m们学到了很多东西,无论在理论上还是实践中,都得到不少的提高,这对于我们以后的工作和学习都有一种巨大的帮助。
附件:
源程序代码
#include"stdio.h"
#include"stdlib.h"
voidCopyL(intSour[],intDist[],intx);//数组Sour复制到数组Dist,复制到x个数
voidSetDI(intDiscL[]);//随机生成磁道数
voidPrint(intPri[],intx);//打印输出数组Pri
voidDelInq(intSour[],intx,inty);//数组Sour把x位置的数删除,并把y前面的数向前移动,y后的数保持不变(即会出现2个y)
voidFCFS(intHan,intDiscL[]);//先来先服务算法(FCFS)
voidSSTF(intHan,intDiscL[]);//最短寻道时间优先算法(SSTF)
intSCAN(intHan,intDiscL[],intx,inty);//扫描算法(SCAN)
voidCSCAN(intHan,intDiscL[]);//循环扫描算法(CSCAN)
//voidN_Step_SCAN(intHan1,intDiscL[]);//N步扫描算法(NStepScan)
voidPaiXu();//寻道长度由低到高排序
voidPri();
intNAll=0;
intBest[5][2];//用作寻道长度由低到高排序时存放的数组
intLimit=0;//输入寻找的范围磁道数i
intJage;
floatAver=0;
intmain()
{
inti;
intDiscLine[10];//声明准备要生成的随机磁道号的数组
intHand;//磁道数
intCon=1;
intn;
while(Con==1)
{
Jage=0;
printf("\n请输入初始的磁道数(0");
scanf("%d",&Hand);
printf("\n+输入寻找的范围:
");
scanf("%d",&Limit);
if(Limit>65536){
printf("超出范围!
");
}
else{
printf("*********************************************\n");
printf("****************磁盘调度算法******************\n");
printf("*********************************************\n");
printf(" *1.先来先服务算法(FCFS)*\n");
printf("*2.最短寻道时间优先算法(SSTF)*\n");
printf("*3.扫描算法(SCAN)*\n");
printf("*4.循环扫描算法(CSCAN)*\n");
printf("*********************************************\n");
scanf("%d",&n);
if(n==0)exit(0);
printf("\n");
switch(n)
{
case1:
SetDI(DiscLine);//随机生成磁道数
FCFS(Hand,DiscLine);//先来先服务算法(FCFS)
break;
case2:
SetDI(DiscLine);//随机生成磁道数
SSTF(Hand,DiscLine);//最短寻道时间优先算法(SSTF)
break;
case3:
SetDI(DiscLine);//随机生成磁道数
SCAN(Hand,DiscLine,0,9);//扫描算法(SCAN)
break;
case4:
SetDI(DiscLine);//随机生成磁道数
CSCAN(Hand,DiscLine);//循环扫描算法(CSCAN)
break;
case5:
SetDI(DiscLine);//随机生成磁道数
FCFS(Hand,DiscLine);//先来先服务算法(FCFS)
SSTF(Hand,DiscLine);//最短寻道时间优先算法(SSTF)
SCAN(Hand,DiscLine,0,9);//扫描算法(SCAN)
CSCAN(Hand,DiscLine);//循环扫描算法(CSCAN)
PaiXu();//寻道长度由低到高排序
printf("\n\n+寻道长度由低到高排序:
");
for(i=0;i<5;i++)
{
printf("%4d",Best[i][0]);
}
break;
}
printf("\n\n+是否继续(按0结束,按1继续)?
");
scanf("%5d",&Con);
}
}
return0;
}
//数组Sour复制到数组Dist,复制到x个数
voidCopyL(intSour[],intDist[],intx)
{
inti;
for(i=0;i<=x;i++)
{
Dist[i]=Sour[i];
}
}
//打印输出数组Pri
voidPrint(intPri[],intx)
{
inti;
for(i=0;i<=x;i++)
{
printf("%5d",Pri[i]);
}
}
//随机生成磁道数
voidSetDI(intDiscL[])
{
inti;
for(i=0;i<=9;i++)
{
DiscL[i]=rand()%Limit;//随机生成10个磁道号
}
printf("+需要寻找的磁道号:
");
Print(DiscL,9);//输出随机生成的磁道号
printf("\n");
}
//数组Sour把x位置的数删除,并把y前面的数向前移动,y后的数保持不变(即会出现2个y)
voidDelInq(intSour[],intx,inty)
{
inti;
for(i=x;i{
Sour[i]=Sour[i+1];
x++;
}
}
//先来先服务算法(FCFS)
voidFCFS(intHan,intDiscL[])
{
intRLine[10];//将随机生成的磁道数数组Discl[]复制给数组RLine[]
inti,k,All,Temp;//Temp是计算移动的磁道距离的临时变量
All=0;//统计全部的磁道数变量
k=9;//限定10个的磁道数
CopyL(DiscL,RLine,9);//复制磁道号到临时数组RLine
printf("\n+按照FCFS算法磁道的访问顺序为:
");
All=Han-RLine[0];
for(i=0;i<=9;i++)
{
Temp=RLine[0]-RLine[1];//求出移动磁道数,前一个磁道数减去后一个磁道数得出临时的移动距离
if(Temp<0)
Temp=(-Temp);//移动磁道数为负数时,算出相反数作为移动磁道数
printf("%5d",RLine[0]);
All=Temp+All;//求全部磁道数的总和
DelInq(RLine,0,k);//每个磁道数向前移动一位
k--;
}
Best[Jage][1]=All;//Best[][1]存放移动磁道数
Best[Jage][0]=1;//Best[][0]存放算法的序号为:
1
Jage++;//排序的序号加1
Aver=((float)All)/10;//求平均寻道次数
printf("\n+移动磁道数:
<%5d>",All);
printf("\n+平均寻道长度:
*%0.2f*",Aver);
}
//最短寻道时间优先算法(SSTF)
voidSSTF(intHan,intDiscL[])
{
inti,j,k,h,All;
intTemp;//Temp是计算移动的磁道距离的临时变量
intRLine[10];//将随机生成的磁道数数组Discl[]复制给数组RLine[]
intMin;
All=0;//统计全部的磁道数变量
k=9;//限定10个的磁道数
CopyL(DiscL,RLine,9);//复制磁道号到临时数组RLine
printf("\n+按照SSTF算法磁道的访问顺序为:
");
for(i=0;i<=9;i++)
{
Min=64000;
for(j=0;j<=k;j++)//内循环寻找与当前磁道号最短寻道的时间的磁道号
{
if(RLine[j]>Han)//如果第一个随机生成的磁道号大于当前的磁道号,执行下一句
Temp=RLine[j]-Han;//求出临时的移动距离
else
Temp=Han-RLine[j];//求出临时的移动距离
if(Temp{
Min=Temp;//Temp临时值赋予Min
h=j;//把最近当前磁道号的数组下标赋予h
}
}
All=All+Min;//统计一共移动的距离
printf("%5d",RLine[h]);
Han=RLine[h];
DelInq(RLine,h,k);//每个磁道数向前移动一位
k--;
}
Best[Jage][1]=All;//Best[][1]存放移动磁道数
Best[Jage][0]=2;//Best[][0]存放算法的序号为:
2
Jage++;//排序序号加1
Aver=((float)All)/10;//求平均寻道次数
printf("\n+移动磁道数:
<%5d>",All);
printf("\n+平均寻道长度:
*%0.2f*",Aver);
}
//扫描算法(SCAN)
intSCAN(intHan,intDiscL[],intx,inty)
{
intj,n,k,h,m,All;
intt=0;
intTemp;
intMin;
intRLine[10];//将随机生成的磁道数数组Discl[]复制给数组RLine[]
intOrder;
Order=1;
k=y;
m=2;//控制while语句的执行,即是一定要使当前磁道向内向外都要扫描到
All=0;//统计全部的磁道数变量
CopyL(DiscL,RLine,9);//复制磁道号到临时数组RLine
printf("\n+按照SCAN算法磁道的访问顺序为:
");
Min=64000;
for(j=x;j<=y;j++)//寻找与当前磁道号最短寻道的时间的磁道号
{
if(RLine[j]>Han)//如果第一个随机生成的磁道号大于当前的磁道号,执行下一句
Temp=RLine[j]-Han;//求出临时的移动距离
else
Temp=Han-RLine[j];//求出临时的移动距离
if(Temp{
Min=Temp;//Temp临时值赋予Min
h=j;//把最近当前磁道号的数组下标赋予h
}
}
All=All+Min;
printf("%5d",RLine[h]);
if(RLine[h]>=Han){//判断磁道的移动方向,即是由里向外还是由外向里
Order=0;
t=1;
}
Han=RLine[h];
DelInq(RLine,h,k);//每个磁道数向前移动一位
k--;
while(m>0)
{
if(Order==1)//order是判断磁盘扫描的方向标签,order是1的话,磁道向内移动
{
for(j=x;j<=y;j++)
{
h=-1;
Min=64000;
for(n=x;n<=k;n++)//判断离当前磁道最近的磁道号
{
if(RLine[n]<=Han)
{
Temp=Han-RLine[n];
if(Temp{
Min=Temp;//Temp临时值赋予Min
h=n;//把最近当前磁道号的数组下标赋予h
}
}
}
if(h!
=-1)
{
All=All+Min;//叠加移动距离
printf("%5d",RLine[h]);
Han=RLine[h];//最近的磁道号作为当前磁道
DelInq(RLine,h,k);
k--;
}
}
Order=0;//当完成向内的移动,order赋予0,执行else语句,使