磁盘驱动调度算法的模拟.docx
《磁盘驱动调度算法的模拟.docx》由会员分享,可在线阅读,更多相关《磁盘驱动调度算法的模拟.docx(12页珍藏版)》请在冰豆网上搜索。
磁盘驱动调度算法的模拟
一. 编写目的
熟悉磁盘的结构以及磁盘的驱动调度算法的模拟,编程实现简单常用的磁盘驱动调度算法先来先服务(FIFO)、电梯调度算法、最短寻找时间优先算法、扫描(双向扫描)算法、单向扫描(循环扫描)算法等。
编程只需实现两个算法。
题目可以选取教材或习题中的相关编程实例。
编程语言建议采用c/c++或Java。
模拟程序鼓励采用随机数技术、动态空间分配技术,有条件的最好能用图形界面展现甚至用动画模拟。
实验性质:
验证型。
二. 课程设计内容
1)掌握使用一门语言进行磁盘驱动调度算法的模拟;
2)编写程序将磁盘驱动调度算法的过程和结果能以较简明直观的方式展现出来。
三. 设计、方法和步骤
1.设计
磁盘驱动调度对磁盘的效率有重要影响。
磁盘驱动调度算法的好坏直接影响辅助存储器的效率,从而影响计算机系统的整体效率。
常用的磁盘驱动调度算法有:
最简单的磁盘驱动调度算法是先入先出(FIFO)法。
这种算法的实质是,总是严格按时间顺序对磁盘请求予以处理。
算法实现简单、易于理解并且相对公平,不会发生进程饿死现象。
但该算法可能会移动的柱面数较多并且会经常更换移动方向,效率有待提高。
最短寻找时间优先算法:
总是优先处理最靠近的请求。
该算法移动的柱面距离较小,但可能会经常改变移动方向,并且可能会发生进程饥饿现象。
电梯调度:
总是将一个方向上的请求全部处理完后,才改变方向继续处理其他请求。
扫描(双向扫描):
总是从最外向最里进行扫描,然后在从最里向最外扫描。
该算法与电梯调度算法的区别是电梯调度在没有最外或最里的请求时不会移动到最外或最里柱面,二扫描算法总是移到最外、最里柱面。
两端的请求有优先服被务的迹象。
循环扫描(单向扫描):
从最外向最里进行柱面请求处理,到最里柱面后,直接跳到最外柱面然后继续向里进行处理。
该算法与扫描算法的区别是,回来过程不处理请求,基于这样的事实,因为里端刚被处理。
2.设计方法
1)使用流程图描述演示程序的设计思想;
2)选取c/c++、Java等计算机语言,编程调试,最终给出运行正确的程序。
3.程序步骤
参考程序:
1) c/c++版的驱动调度算法-电梯调度模拟程序
#include
#include
#include
#include
typedefstruct_proc
{charname[32];/*定义进程名称*/
intteam;/*定义柱面号*/
intci;/*定义磁道面号*/
intrec;/*定义记录号*/
struct_proc*prior;
struct_proc*next;
}PROC;
PROC*g_head=NULL,*g_curr=NULL,*local;
intrecord=0;
intyi=1;
voidinit()
{
PROC*p;/*初始化链表(初始I/O表)*/
g_head=(PROC*)malloc(sizeof(PROC));
g_head->next=NULL;
g_head->prior=NULL;
p=(PROC*)malloc(sizeof(PROC));
strcpy(p->name,"P1");
p->team=100;
p->ci=10;
p->rec=1;
p->next=NULL;
p->prior=g_head;
g_head->next=p;
g_curr=g_head->next;
p=(PROC*)malloc(sizeof(PROC));
strcpy(p->name,"P2");
p->team=30;
p->ci=5;
p->rec=5;
p->next=NULL;
p->prior=g_curr;
g_curr->next=p;
g_curr=p;
p=(PROC*)malloc(sizeof(PROC));
strcpy(p->name,"P3");
p->team=40;
p->ci=2;
p->rec=4;
p->next=NULL;
p->prior=g_curr;
g_curr->next=p;
g_curr=p;
p=(PROC*)malloc(sizeof(PROC));
strcpy(p->name,"P4");
p->team=85;
p->ci=7;
p->rec=3;
p->next=NULL;
p->prior=g_curr;
g_curr->next=p;
g_curr=p;
p=(PROC*)malloc(sizeof(PROC));
strcpy(p->name,"P5");
p->team=60;
p->ci=8;
p->rec=4;
p->next=NULL;
p->prior=g_curr;
g_curr->next=p;
g_curr=g_head->next;
local=(PROC*)malloc(sizeof(PROC));/*选中进程*/
strcpy(local->name,"P0");
local->team=0;
local->ci=0;
local->rec=0;
local->next=NULL;
local->prior=NULL;
}
voidPrintInit()/*打印I/O表*/
{
PROC*t=g_head->next;
printf("-------------------------------------/n");
printf("---------I/OLIST---------/n");
printf("processteamcirec/n");
while(t!
=NULL)
{
printf("%4s%8d%8d%5d/n",t->name,t->team,t->ci,t->rec);
t=t->next;
}
printf("/n/nCurrentprocessis:
/n");
printf("------------------------------/n/n");
printf("processteamcirec/n");
printf("%4s%8d%8d%5d/n",local->name,local->team,local->ci,local->rec);
switch(yi)
{
case1:
{printf("currentdirectionisUP/n");break;}
case0:
{printf("currentdirectionisdown/n");break;}
}
}
voidacceptreq()/*接受请求函数*/
{
PROC*p;
p=(PROC*)malloc(sizeof(PROC));
printf("pleaseinputtheinformationofthenewprocess/nprocess-name:
/nprocess-team/nprocess-ci/nprocess-rec/n");
printf("1.name/n");
scanf("%s",p->name);
printf("2.team0-199/n");
scanf("%d",&p->team);/*输入请求进程信息*/
printf("3.ci0-19/n");
scanf("%d",&p->ci);
printf("4.rec0-7/n");
scanf("%d",&p->rec);
getchar();
g_curr=g_head;/*将此节点链入I/O请求表*/
while(g_curr->next!
=NULL)
g_curr=g_curr->next;
p->next=NULL;
p->prior=g_curr;
g_curr->next=p;
g_curr=g_head->next;
printf("NEWI/OLIST/n/n");
PrintInit();/*将新的I/O请求表输出*/
}
voidqddd()/*驱动调度函数*/
{PROC*out;
intmin;
intmax=g_head->next->team;
if(g_head->next==NULL);/*若已全部调度,则空操作*/
else{switch(yi)
{case1:
{
min=g_head->next->team;out=g_head->next;/*选出最小的team进程,模拟启动此进程*/
strcpy(local->name,out->name);
local->team=out->team;
local->ci=out->ci;
local->rec=out->rec;
for(g_curr=g_head->next;g_curr!
=NULL;g_curr=g_curr->next)
{
if(g_curr->team>record)
{min=g_curr->team;break;}
}
for(g_curr=g_head->next;g_curr!
=NULL;g_curr=g_curr->next)
{
if(min>=g_curr->team&&g_curr->team>record)
{
min=g_curr->team;
out=g_curr;
strcpy(local->name,out->name);
local->team=out->team;
local->ci=out->ci;
local->rec=out->rec;
}
}
printf("/n-----------------------/n");
printf("theprocesschoosed:
/n");
printf("processteamcirec/n");
printf("%4s%8d%8d%5d/n",out->name,out->team,out->ci,out->rec);
record=local->team;
printf("%d",record);
for(g_curr=g_head->next;g_curr!
=NULL;g_curr=g_curr->next)
{
if(maxteam)
max=g_curr->team;
}
if(max==record)
{
yi=0;
record=1000;
break;
}
break;
}/*case1*/
case0:
/*case1的对称过程*/
{
max=g_head->next->team;out=g_head->next;
strcpy(local->name,out->name);
local->team=out->team;
local->ci=out->ci;
local->rec=out->rec;
for(g_curr=g_head->next;g_curr!
=NULL;g_curr=g_curr->next)
{
if(g_curr->team{max=g_curr->team;break;}
}
for(g_curr=g_head->next;g_curr!
=NULL;g_curr=g_curr->next)
{
if(max<=g_curr->team&&g_curr->team{
max=g_curr->team;
out=g_curr;
strcpy(local->name,out->name);
local->team=out->team;
local->ci=out->ci;
local->rec=out->rec;
}
}
printf("/n-----------------------/n");
printf("theprocesschoosed:
/n");
printf("processteamcirec/n");
printf("%4s%8d%8d%5d/n",out->name,out->team,out->ci,out->rec);
min=g_head->next->team;
for(g_curr=g_head->next;g_curr!
=NULL;g_curr=g_curr->next)
{
if(min>g_curr->team)
min=g_curr->team;
}
record=local->team;
if(min==record)
{
yi=1;
record=0;
break;
}
break;
}
default:
return-1;
}/*switch*/
if(out->next==NULL)/*将选中的进程从I/O请求表中删除*/
{
out->prior->next=NULL;
free(out);
}
else
{
out->prior->next=out->next;
out->next->prior=out->prior;
free(out);
}
}/*else*/
}
voidacceptnum()/*通过输入0~1选择‘驱动调度’或是‘接受请求’*/
{
floatnum;
charc;
while
(1)
{
printf("----------------------------------------------/n");
printf("pleaseinputanumberbetween0and1/nnum<=0.5:
acceptrequest/nnum>0.5:
qudongdiaodu/n/nnum==2:
I/OLIST/n/nnum=?
/n");
scanf("%f",&num);
getchar();
while((num<0||num>1)&&num!
=2)/*过滤不合法数据注意:
本程序其他输入数据可能未过滤*/
{
printf("numberERROR!
Inputagainplease!
/nnum=?
/n");
scanf("%f",&num);
getchar();
}
if(num>0.5&&num!
=2)/*驱动调度*/
{
if(g_head->next==NULL)
{
printf("/n/n");
printf("---------------------/n");
printf("I/Olistisempty!
!
!
/n");/*请求表为空无需调度*/
}
else
{
printf("qudongdiaodu/n");
qddd();
/*调用函数进行调度*/
}
}
elseif(num<=0.5)/*接受请求*/
{
printf("acceptrequest/n/n");
acceptreq();
}
elseif(num==2)/*通过输入2显示当前请求I/O表*/
{
printf("I/OLIST;");
printf("-------------------/n");
PrintInit();
printf("/n");
}
printf("-----------------------/n");
printf("choose'n'toquitelsetocontinue/n");/*输入n离开本程序*/
if(strcmp(c=getchar(),'n')==0||strcmp(c=getchar(),'N')==0)
{
clrscr();
printf("/n/n/n/n/n/n");
printf("thankyoufortestingmyprogram!
/n");
printf("---by01/n");
sleep
(2);
printf("/n/nBYEbye!
!
");
sleep
(2);
return-1;
}
else
{
clrscr();
}
}
}
main()/*主程序*/
{
init();
PrintInit();
acceptnum();
}
设计体会
能够将磁盘驱动调度算法在各种情况下都能得出正确的结论。
对FIFO、最短寻找时间优先或电梯调度算法能够在多次模拟数据下得出平均移动柱面数,并进行效率比较分析。
2011-2012学年第一学期
操作系统
课程设计报告
班级
学号
姓名
成绩
指导教师于复兴