磁盘移臂调度过程模拟设计-电梯算法_最短寻道时间优先教学文案
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
磁盘移臂调度过程模拟设计-电梯算法_最短寻道时间优先
学号:
课程设计
题目
磁盘移臂调度过程模拟设计
--电梯算法、最短寻道时间优先算
法
学院计算机科学与技术学院
专业
班级
姓名
指导教师吴利军
2013 年 1 月15 日
课程设计任务书
学生姓名:
指导教师:吴利军工作单位:计算机科学与技术学院
题目: 磁盘移臂调度过程模拟设计——电梯算法、最短寻道时间优先算法初始条件:
1.预备内容:阅读操作系统的文件管理章节内容,理解有关文件组织形式、存储设备的概念。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要
求)
1.编程序模拟磁盘调度的过程,采用指定算法,模拟并输出存取臂的移动顺序,并计算存取臂移动的磁道总数。
能够处理以下的情形:
⑴可根据需要输入当前磁头的位置,磁头移动方向;
⑵能够输入柱面数,磁道访问序列等参数,并能够显示调度结果(磁盘访问
请求的磁道号以及磁头移动的总磁道数)。
2.设计报告内容应说明:
⑴课程设计目的与功能;
⑵需求分析,数据结构或模块说明(功能与框图);
⑶源程序的主要部分;
⑷测试用例,运行结果与运行情况分析;
⑸自我评价与总结:
i)你认为你完成的设计哪些地方做得比较好或比较出色;
ii)什么地方做得不太好,以后如何改正;
iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教
训);
iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);
v)对实验题的评价和改进意见,请你推荐设计题目。
时间安排:
设计安排一周:周1、周2:完成程序分析及设计。
周2、周3:完成程序调试及测试。
周4、周5:验收,撰写课程设计报告。
(注意事项:严禁抄袭,一旦发现,抄与被抄的一律按0分记)
指导教师签名:年月日
系主任(或责任教师)签名:年月日
磁盘移臂调度过程模拟设计
——电梯算法、最短寻道时间优先算法1 课程设计目的与功能
操作系统课程设计,主要是在学习操作系统课程并完成操作系统各部分实验的基础上,对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理功能的认识,进一步分析各个部分之间的联系,以达到对完整系统的理解。
有助于提高运用操作系统知识解决实际问题的能力;锻炼实际的编程能力及创新能力;提高调查研究、查阅技术文献、资料以及编写软件设计文档的能力。
本课程设计是通过设计一个磁盘调度模拟系统,深入理解磁盘的工作原理,从而使磁盘调度更加形象化,容易使人理解,使磁盘调度的特点更简单明了,能使使用者加深对磁盘调度算法的理解。
具体实现为,运用一门高级编程语言编写程序模拟磁盘调度的过程,采用先来先服务算法和电梯算法,模拟并输出存取臂的移动顺序,并计算存取臂移动的磁道总数。
能够处理以下的情形:
(1)可根据需要输入当前磁头的位置,磁头移动方向;
(2)能够输入柱面数,磁道访问序列等参数,并能够显示调度结果(磁盘访问请求的
磁道号以及磁头移动的总磁道数)。
2 需求分析
2.1磁盘的工作原理
磁盘是最典型的直接存取设备。
磁盘设备允许文件系统直接存取磁盘上的任意物理块。
为了存取一个特定的物理块,磁头将直接移动到所要求的位置上,而不需要像顺序存取那样事先存取其他的物理块。
磁盘机各类很多,但一般由一些磁盘片组成的磁盘组组成。
其中每个磁盘片对应一个装有读写磁头的磁头臂,磁头臂上的两个读写磁头分别对磁盘片的上下两面进行读写。
系统在对磁盘进行初始化处理时,把每个磁盘片分割成一些大小相等的扇区。
在磁盘转动时经过读写磁头所形成的圆形轨迹称为磁道。
由于磁头臂可沿半径方向移动,因此,磁盘上有多条磁道。
另外,人们通常把所有磁盘片的相同磁道称为一个柱面,因此,磁盘上每个物理块的位置可以用柱面号、磁头号和扇区号表示,这些地址和物理块号一一对应。
2.2磁盘的调度算法
操作系统中,对磁盘的访问要求来自多方面,常常需要排队。
这时,对众多的访问要求按一定的次序响应,会直接影响磁盘的工作效率,进而影响系统的性能。
访问磁盘的时间因子由3部分构成,它们是查找(查找磁道)时间、等待(旋转等待扇区)时间和数据传输时间,其中查找时间是决定因素。
因此,磁盘调度算法先考虑优化查找策略,需要时再优化旋转等待策略。
主要的磁盘调度算法有下面四种:
(1)先来先服务算法(FCFS):
这是一种比较简单的磁盘调度算法。
它根据进程请求访问磁盘的先后次序进行调度。
此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。
此算法由于未对寻道进行优化,在对磁盘的访问请求比较多的情况下,此算法将降低设备服务的吞吐量,致使平均寻道时间可能较长,但各进程得到服务的响应时间的变化幅度较小。
(2)最短寻道时间优先算法(SSTF):
该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,该算法可以得到比较好的吞吐量,但却不能保证平均寻道时间最短。
其缺点是对用户的服务请求的响应机会不是均等的,因而导致响应时间的变化幅度很大。
在服务请求很多的情况下,对内外边缘磁道的请求将会无限期的被延迟,有些请求的响应时间将不可预期。
(3)扫描算法(SCAN),即电梯算法:
扫描算法不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头的当前移动方向。
例如,当磁头正在自里向外移动时,扫描算法所选择的下一个访问对象应是其欲访问的磁道既在当前磁道之外,又是距离最近的。
这样自里向外地访问,直到再无更外的磁道需要访问才将磁臂换向,自外向里移动。
这时,同样也是每次选择这样的进程来调度,即其要访问的磁道,在当前磁道之内,从而避免了饥饿现象的出现。
由于这种算法中磁头移动的规律颇似电梯的运行,故又称为电梯调度算法。
此算法基本上克服了最短寻道时间优先算法的服务集中于中间磁道和响应时间变化比较大的缺点,而具有最短寻道时间优先算法的优点即吞吐量较大,平均响应时间较小,但由于是摆动式的扫描方法,两侧磁道被访问的频率仍低于中间磁道。
(4)循环扫描算法(CSCAN):
循环扫描算法是对扫描算法的改进。
如果对磁道的访问请求是均匀分布的,当磁头到达磁盘的一端,并反向运动时落在磁头之后的访问请求相对较少。
这是由于这些磁道刚被处理,而磁盘另一端的请求密度相当高,且这些访问请求等待的时间较长,为了解决这种情况,循环扫描算法规定磁头单向移动。
例如,只自里向外移动,当磁头移到最外的被访问磁道时,磁头立即返回到最里的欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描。
3数据结构或模块说明
3.1数据结构
3.2函数
程序中有三个函数:
void sorting( )——初始化柱面总数、磁头初始位置、磁头初始移动方向、申请访问的磁道序列。
void sstf( )——对磁盘移臂调度的最短寻道时间优先算法进行模拟,输出磁道访问序列和磁头移动的总磁道数。
void scan( )——对磁盘移臂调度的电梯算法进行模拟,输出磁道访问序列和磁头移动的总磁道数。
3.3模块框图
程序分为四大模块,分别为数据初始化、访问序列排序,电梯算法调度和最短寻道时间优先算法调度,依靠sorting,scan,sstf三个函数实现。
程序总流程如下:
4 源程序
#include<stdio.h> #include<stdlib.h> #define MAX 20
int run_number; //记录实际柱面数
int run[MAX]; //记录每道的磁道序列
int run_jilu[MAX];
int daoshu;
bool FLAG_USED[MAX];
int abs_LONGTH[MAX];
int abs_number(int a,int b)
{
if(a>b)
return a-b;
else
return b-a;
}
int cmp(const void *a,const void *b)
{
int x=*(int *)a;
int y=*(int *)b;
return (x<y?-1:x>y?1:0);
}
//电梯算法,当flag=false向下走
void SCAN(int run[],int run_jilu[],int run_begin,bool flag) {
int jilu,j,i;
bool flag_t=false;
//如果开始位置在序列中就继续执行,否则加入其中
for( i=0;i<run_number;i++)
{
if(run_begin==run[i])
{
break;
}
}
if(i==run_number)
{
run_number+=1;
run[run_number-1]=run_begin;
}
//快排序
qsort(run,run_number,sizeof(int),cmp); for(i=0;i<run_number;i++)
{
if(run_begin==run[i])
{
jilu=i;
break;
}
}
if(flag==false)
{
j=0;
for(i=jilu;i>=0;i--)
{
run_jilu[j]=run[i];
j++;
}
if(i<0)flag_t=true;
if(flag_t=true)
{
for(i=jilu+1;i<run_number;i++)
{
run_jilu[j]=run[i];
j++;
}
}
daoshu=run_begin-run[0]+run[run_number-1]-run[0]; }
if(flag==true)
{
j=0;
for(i=jilu;i<run_number;i++)
{
run_jilu[j]=run[i];
j++;
}
if(i<0)flag_t=true;
if(flag_t=true)
{
for(i=jilu-1;i>=0;i--)
{
run_jilu[j]=run[i];
j++;
}
}
daoshu=run[run_number-1]-run_begin+run[run_number-1]-run[0]; }
}
//
bool end_not(bool a[])
{
for(int i=0;i<run_number;i++)
{
if(a[i]==false)
return false;
}
return true;
}
//最短寻道时间算法
void SSTF(int run[],int run_jilu[],int run_begin)
{
int jilu,temp,flag,i,j;
flag=0;
run_jilu[flag]=run_begin;
daoshu=0;
//如果开始位置在序列中就继续执行,否则加入其中
for( i=0;i<run_number;i++)
{
if(run_begin==run[i])
{
break;
}
}
if(i==run_number)
{
run_number+=1;
run[run_number-1]=run_begin;
}
for(i=0;i<run_number;i++)
{
FLAG_USED[i]=false;
}
for(i=0;i<run_number;i++)
{
if(run_begin==run[i])
{
jilu=i;
break;
}
}
FLAG_USED[jilu]=true;
//当没走完时
while(!end_not(FLAG_USED))
{
for( j=0;j<run_number;j++)
{
abs_LONGTH[j]=abs_number(run_begin,run[j]);
}
for(j=0;j<run_number;j++)
{
if(FLAG_USED[j]==false)
{
temp=abs_LONGTH[j];
break;
}
}
for(i=0;i<run_number;i++)
{
if(temp>abs_LONGTH[i]&&FLAG_USED[i]==false)
temp=abs_LONGTH[i];
}
for(i=0;i<run_number;i++)
{
if(temp==abs_LONGTH[i]&&FLAG_USED[i]==false)
{
run_begin=run[i];
flag++;
run_jilu[flag]=run_begin;
FLAG_USED[i]=true;
break;
}
}
}
for(flag=0;flag<run_number-1;flag++)
{
daoshu+=abs_number(run_jilu[flag+1],run_jilu[flag]);
}
}
int main()
{
int run_begin,as,at,i;
bool flag;
printf("请输入柱面数:");
scanf("%d",&run_number);
printf("请输入各道磁道数\n");
for( i=0;i<run_number;i++)
{
scanf("%d",&run[i]);
}
printf("请输入开始磁道数:");
scanf("%d",&run_begin);
printf("请选择寻道方式(1--电梯算法,2--最短寻道)");
scanf("%d",&at);
while(at!=1&&at!=2)
{
printf("请选择寻道方式(1--电梯算法,2--最短寻道)");
scanf("%d",&at);
}
if(at==1)
{
printf("请输入走向(1--上,2——下):");
scanf("%d",&as);
while(as!=1&&as!=2)
{
printf("请输入走向(1--上,2——下):");
scanf("%d",&as);
}
if(as==1)
{
flag=true;
}
if(as==2)
{
flag=false;
}
SCAN(run,run_jilu,run_begin,flag);
}
if(at==2)
{
SSTF(run,run_jilu,run_begin);
}
printf("走道次序:");
for(i=0;i<run_number;i++)
{
printf("%d\t",run_jilu[i]);
}
printf("\n走过总道数:%d\n",daoshu);
system("pause");
return 0;
}
4 自我评价与总结
通过这次的课程设计,我认识到要将操作系统这门计算机专业课学好的不易——不仅仅是要把书上的基本知识学好,而且还要不断进行实践,将所学与实践操作结合起来才能更好地巩固所学,才能提高自己实践能力。
可以说,此课程设计的理论难度并不大,但是若要增强程序的健壮性并且实际去编程实现,就遇到了相当大的难度。
例如测试中提到的对int型数据的非法输入的报错等,都是可以改进的部分,为此也翻阅过资料,网络上提供的修改方案是利用while(!cin>>total)实现报错,但在VC++6.0环境中不能运行,故还是没有解决。
总的说来,与之涉及的很多方面并没有学过,自己还需要去自学和实践检验。
所以在以后的学习中一方面我要不断的巩固自己所学的理论知识,一方面还要多参加实际操作工作以便提高自己的实际操作能力。
本科生课程设计成绩评定表
注:最终成绩以五级分制记。
优(90-100分)、良(80-89分)、中(70-79分)、
及格(60-69分)、60分以下为不及格
指导教师签名:
2013 年 1月15 日。