驱动调度完整版绝对版验收最高分版注释最详细版.docx
- 文档编号:25423305
- 上传时间:2023-06-08
- 格式:DOCX
- 页数:33
- 大小:280.67KB
驱动调度完整版绝对版验收最高分版注释最详细版.docx
《驱动调度完整版绝对版验收最高分版注释最详细版.docx》由会员分享,可在线阅读,更多相关《驱动调度完整版绝对版验收最高分版注释最详细版.docx(33页珍藏版)》请在冰豆网上搜索。
驱动调度完整版绝对版验收最高分版注释最详细版
石家庄经济学院
《计算机操作系统》
课程设计报告
实验名称驱动调度
学号
姓名刘文龙
指导教师
日期2013年6月17日
合作伙伴
一、实验题目
模拟电梯调度算法,实现对磁盘的驱动调度。
二、实验目的
本实验要求学生模拟设计一个驱动调度程序,观察驱动调度程序的动态运行过程。
通过实验使学生理解和掌握驱动调度的职能。
三、实验内容
1.总体实验内容
磁盘是一种高速、大容量、旋转型、可直接存取的存储设备。
它作为计算机系统的辅助存储器,担负着繁重的输入输出任务。
在多道程序设计系统中,往往同时会有若干个要求访问磁盘的输入输出请求等待处理。
系统可采用一种策略,尽可能按最佳次序执行要求访问磁盘的请求,这就叫驱动调度。
所采用的调度算法称“驱动调度算法”。
磁盘是可供多个进程共享的存储设备,但一个磁盘在某时刻只能为一个进程服务。
当有
程在访问某个磁盘时,其他想访问该磁盘的进程必须等待,直到磁盘一次工作结束。
当有多个进程提出输入输出要求而处于等待状态时,可用电梯调度算法从若干个等待访问者中选择一个进程,让它访问磁盘。
选择访问者的工作由“驱动调度”进程来完成。
2.实验分工
刘文龙:
驱动调度.h与随机数.h
张瑜:
主函数与进程请求.h
马同乐:
驱动调度.h与结构体定义.h
四、实验设计与分析
(1)各函数的调用关系如图1。
(2)驱动调度能降低为若干个输入输出请求服务所需的总时间,从而提高系统效率。
模拟电梯调度算法,对磁盘进行移臂和旋转调度
“驱动调度”进程和“接收请求”进程能否占有处理器运行,取决于磁盘的结束中断信号和处理器调度策略。
在实验中可用随机数来模拟确定这两个进程的运行顺序,以代替中断处理和处理器调度选择的过程。
因而,程序的结构可参考图2。
(3)由于磁盘与处理器是可以并行工作的、所以当磁盘在作为一个进程服务时,占有处理器的另一进程可以提出使用磁盘的要求,也就是说,系统能动态地接收新的输入输出请求。
为了模拟这种情况,在本实验中设置了一个“接收请求”进程。
“接收请求”进程建立一张“请求I/O”表,指出访问磁盘的进程要求访问的物理地址,表的格式为:
进程名柱面号磁道号物理记录号
假定某个磁盘组共有200个柱面,由外向里顺序编号(0—199),每个柱面上有20个磁道,编号为0—19,每个磁道分成8个物理记录,编号0—7。
进程访问磁盘的物理地址可以用键盘输入的方法模拟得到。
图3是“接收请求”进程的模拟算法。
图2中的初始化工作包括,初始化“请求I/O”表,置当前移臂方向为里移;置当前位置为0号柱面,0号物理记录。
程序运行前可假定“请求I/O”表中已经有如干个进程等待访问磁盘。
(4)“驱动调度”进程的功能是查“请求I/O”表,当有等待访问磁盘的进程时,按电梯调度算法从中选择一个等待访问者,按该进程指定的磁盘物理地址启动磁盘为其服务。
对移动臂磁盘来说,驱动调度分移臂调度和旋转调度。
电梯调度算法的调度策略是与移动臂的移动方向和移动臂的当前位子有关的,所以每次启动磁盘时都应登记移动臂方向和当前位子。
电梯调度算法是一种简单而实用的驱动调度方法,这种调度策略总是优先选择与当前柱面号相同的访问请求,从这些请求中再选择一个能使旋转距离最短的等待访问者。
如果没有与当前柱面号相同的访问请求,则根据移臂方向来选择,每次总是沿臂移动方向选择一个与当前柱面号最近的访问请求,若沿这个方向没有访问请求时,就改变臂的移动方向。
这种调度策略能使移动臂的移动频率极小,从而提高系统效率。
用电梯调度算法实现驱动调度的模拟算法如图4
五、测试结果及其分析
1.测试方案
(1)测试实例
进程名柱面号磁道号物理记录号
P17617
P218321
P3944
(2)实验测试过程
<1>生成随机数,根据随机数的大小判断是进行电梯调度还是旋转调度如图1
图1
<2>生成的随机数是0.347942,因为0.347942<=0.5,所以转用采用接受请求
输入的数据是按照“请求I/O”表的格式如图2
进程名柱面号磁道号物理记录号
P17617
输入完成后点击回车,并且输入y或者Y,表示继续。
系统又分配了一个随机数0.7906809,表示进行电梯调度,因为当前请求表里面只有P1所以选择的进程只有P1。
图2
<3>选择继续Y或者y,这时候系统会调用随机函数,产生一个随机数0.909848,因为0.909848>0.5,因此转入电梯电镀,因为请求表里面是空的,所以,显示请求表为空。
如图3
图3
<4>选择继续Y或者y,这时候系统会调用随机函数,产生一个随机数0.659536,因为0.659536>0.5因此转入电梯调度,由于当前请求I/O为空,所以显示请求I/O为空。
如图4
图4
<5>选择继续Y或者y,这时候系统会调用随机函数,产生一个随机数0.0656148,因为0.0656148<0.5因此转入接受请求。
输入的数据是按照“请求I/O”表的格式.如图5
进程名柱面号磁道号物理记录号
P218321
P3944
图5
<6>选择继续Y或者y,这时候系统会调用随机函数,产生一个随机数0.971099,因为0.971099>0.5因此转入电梯调度。
如图6
图6
<7>因为P1进程的柱面号是76,物理记录号为7,因为P2的柱面号是183,大于P1的柱面号,所以方向向里,选择的进程是P2。
选择继续,系统分配了一个随机数0.642872,转入电梯调度如图7
图7
<8>因为当前的柱面号是183,P3进程的柱面号是9,小于183,所以方向向外(down).,选择进程P3。
如图8
图8
<9>选择继续,随机数是0.924131,这时I/O请求表里面是空的。
如图9
图9
(3)测试结果
当输入第一组数据时系统又分配了一个随机数0.7906809,表示进行电梯调度,因为当前请求表里面只有P1所以选择的进程只有P1。
输入第二组数据后选择继续Y或者y,这时候系统会调用随机函数,产生一个随机数0.971099,因为0.971099>0.5因此转入电梯调度。
因为P1进程的柱面号是76,物理记录号为7,因为P2的柱面号是183,大于P1的柱面号,所以方向向里,选择的进程是P2。
选择继续,系统分配了一个随机数0.642872,转入电梯调度,因为当前的柱面号是183,P3进程的柱面号是9,小于183,所以方向向外(down).,选择进程P3。
此时I/O请求表里面的进程是空的。
2.测试方案
(1)测试实例
进程名柱面号磁道号物理记录号
P1166177
P215595
P312245
P410974
P576123
(2)实验测试过程
<1>生成随机数,根据随机数的大小判断是进行电梯调度还是接受请求.如图-11
图-11
<2>输入两组数据,如图-12
图-12
<3>对上面的两组数据进行调度,因为当前的柱面号是0,物理记录号是0。
方向向里,选择柱面号最小的进程p2。
如图-13
如图-13
<4>此时方向向里,p1的柱面号 选择进程p1.如图-14 图-14 <5>输入两组数据。 如图-15 图-15 <6>输入一组数据。 如图-16 图-16 <7>因为没有比当前柱面号大的进程,所以方向向外,选择柱面号最的进程,进行调度,所以选择p3。 如图-17 图-17 <8>现在没有新的进程进入请求表。 如图-18 图-18 <9>选择p4。 如图-19 图-19 <10>选择p5。 如图-20 图-20 (3)测试结果 当有多个进程在当前进程请求表里面的时候,首先判断是否有柱面号相同的进程,如果有,则,优先选择旋转距离小的进程,依次执行。 否则,根据移臂方向选择进程,如果方向向里,则对大于当前进程柱面号的进程中选择柱面号最小的,依次执行,否则,优先选择小于当前柱面号进程中最大的柱面号的进程。 六、实验总结 1、通过设计数据结构进程访问磁盘,我们进一步了解了磁盘存储器的物理结构,对驱动调度有深入的了解。 2、刚刚开始进行实习设计时,对题目没有进行正确的理解就忙于写代码,算法设计考虑的很不全面,从而导致后来实验数据出错,通过再次审查题目及资料,我了解了题目要求,对算法进行了重新设计,最终完成了试验,得出了正确的运行结果。 3、在调试的过程中出现了很多的问题,从语法到算法中的错误,通过向老师和同学请教以及查阅资料,解决了这些问题,使我对编程语句及算法设计有了更深的认识。 编程是很严谨的事情,不容半点马虎,即使是一个括号也可能导致程序的错误。 4、刚开始编译的时候存在一些语法错误,结构体及数组,以及参数传递相关知识都一知半解,对编程语言的运用还没达到很熟练地步,通过这次实验我更好复习和学习了编程语言的一些知识。 5、通过模拟电梯调度算法,实现对磁盘的驱动调度使我更深一步了解了驱动调度,对移动臂磁盘来说,驱动调度又分为移臂调度和旋转调度。 驱动调度分移臂调度和旋转调度。 电梯调度算法的调度策略是与移动臂的移动方向和移动臂的当前位子有关的,所以每次启动磁盘时都应登记移动臂方向和当前位子。 电梯调度算法是一种简单而实用的驱动调度方法,这种调度策略总是优先选择与当前柱面号相同的访问请求,从这些请求中再选择一个能使旋转距离最短的等待访问者。 如果没有与当前柱面号相同的访问请求,则根据移臂方向来选择,每次总是沿臂移动方向选择一个与当前柱面号最近的访问请求,若沿这个方向没有访问请求时,就改变臂的移动方向。 这种调度策略能使移动臂的移动频率极小,从而提高了系统效率。 6、通过这次实验,学习到了很多在课堂上没有学到的知识,不仅仅是操作系统方面的知识,还包括与同学间交流的增长和思维模式。 通过实验使我理解并且掌握了驱动调度的职能。 学到了书上学不到的东西,丰富了知识面收益匪浅,感谢老师的指导 七、源代码 (1)主函数 #include #include"结构体定义.h"//主函数调用"结构体定义.h" #include"进程请求.h"//主函数调用“进程请求” #include"驱动调度.h"//主函数调用“驱动调度” #include"随机数.h"//主函数调用“随机数” usingnamespacestd;//全局命名空间,必须使用namespacestd;这样才能正确使用cout。 voidmain()//主函数 {//--------------------------------------------------------------------------------------------------------------------- cout<<"┌──────────────────────────────────────┐"; cout<<"│请按照如下顺序输入各进程信息,以空格分开,每条进程信息输入完成后按回车键结束: │"; cout<<"│进程名柱面号磁道号物理记录号│";//------打印输出说明------ cout<<"│<=10个字符0-1990-190-7│"; cout<<"└──────────────────────────────────────┙"; //--------------------------------------------------------------------------------------------------------------------- inti; processpro[M];//创建进程数组 for(i=0;i { pro[i].signal=0;//标记没有进入I/O请求表的进程等于0 } intpro_num=0; charsignal='Y'; intpro_count;//进程等待表中进程数 while(signal=='Y'||signal=='y') { if(Ran_Num()>0.5)//如果随即数大于0.5,转到调度模块 { pro_count=0; for(i=0;i { if(pro[i].signal==1) pro_count++;//统计进程等代表中有效进程数 } dri_sch(pro_count,pro);//调用驱动调度 } else//若随机数小于等于0.5,转到接受请求,即创建等待进程表 { pro_count=0;// list(pro_count,pro_num,pro);//调用I/O表 } cout< "< cin>>signal; while(signal! ='Y'&&signal! ='N'&&signal! ='y'&&signal! ='n') { cout<<"输入错误,请输入Y(y)或N(n)"< cin>>signal; } } } (2)结构体定义.h #ifndefPRO_STRUCT_H//#ifndefx先测试x是否被宏定义过 #definePRO_STRUCT_H//如果标识PRO_STRUCT_H没有被定义,则重定义标示PRO_STRUCT_H #defineN10 typedefstructProcess//定义一个结构体 { charname[N];//进程名 intcyl_num;//请求的柱面号 inttra_num;//请求的磁道号 intrec_num;//请求的物理记录号 intsignal;//标记位 }process;//结构体的别名 #endif//#endif用于结束条件编译,编译时与前面最近的#if、#ifdef或#ifndef作为一对,经常一起使用,编译两者之间的部分程序段。 /********************************** 语句1#ifndef标识1 语句2#define标识1 语句3#endif 语句4…… 语句5…… 该段代码意思是: 如果标识1没有被定义,则重定义标示1,即执行语句2、语句3、语句4、……;如果标识1已经被定义,则直接跳过语句2、语句3,直接执行语句4、语句5、…… /***********************************/ (3)进程请求.h #ifndefPRO_LIST_H #definePRO_LIST_H #include #include #include"结构体定义.h" usingnamespacestd;//全局命名空间,必须使用namespacestd;这样才能正确使用cout。 #defineM100 voidlist(intpro_count,intpro_num,processpro[M])//创建等待进程表-----pro_count表中的进程数------pro_num等待的进程数-------pro[M]结构体名,里面含有进程的名字,柱面号,磁道号 { cout<<"等待的进程数: "; cin>>pro_num;//pro_num等待的进程数 if(pro_num>0&&(pro_num+pro_count)<=M)//判断要输入的进程数是否合法,输入后是否超出进程等待表所允许的最大值 { cout<<"开始输入"< inti,j=0,h; for(i=0;i { for(j=0;pro[i].signal==0&&j { cin>>pro[i].name>>pro[i].cyl_num>>pro[i].tra_num>>pro[i].rec_num;//***cyl_num柱面号***----name[N];//进程名***----tra_num请求的磁道号***----rec_num请求的物理记录号 for(h=0;h { if(pro[h].signal==1)//***----signal标记位,表示是否有进程请求等待***---- { while(strcmp(pro[h].name,pro[i].name)==0||strlen(pro[i].name)>10) { cout<<"进程名不合规定,超出指定长度或已存在,请重新输入进程名: "< cin>>pro[i].name; } } } while(pro[i].cyl_num<0||pro[i].cyl_num>199)//判断柱面号是否越界 { cout<<"柱面号不合规定,请重新输入柱面号: "< cin>>pro[i].cyl_num; } while(pro[i].tra_num<0||pro[i].tra_num>19)//判断磁道号是否越界 { cout<<"磁道号不合规定,请重新输入磁道号: "< cin>>pro[i].tra_num; } while(pro[i].rec_num<0||pro[i].rec_num>7)//判断物理记录号是否越界 { cout<<"物理记录号不合规定,请重新输入物理记录号: "< cin>>pro[i].rec_num; } pro[i].signal=1; } } } else { if(pro_num<=0) { cout<<"要输入的进程个数必须为正整数"< } else { cout<<"进程数超出进程等待表所允许的最大量"< cout<<"当前最多允许输入"<<(M-pro_count)<<"个进程"< } } } #endif (4)驱动调度.h #include #include 主要是对cin,cout之类的一些操纵运算 #include"进程请求.h" #include"结构体定义.h" intdir=0;//0,up向里由小到大,由里向里;1,down由大到小,向外 intcylinder=0;//置当前柱面号为0 intrecord=0;//置当前记录号为0 intmin_rec=0;//移动到当前进程扇区所要移动的距离 intmin_r=8;//旋转调度中最小移动距离 intmax_min_cyl=200;//大于当前柱面号的访问请求中的最小者 intmin_max_cyl=0;//小于当前柱面号的访问请求中的最大者 intx; intchoosen=0;//被选中的进程 //-------------------------------------------------------*****旋转调度*****---------------------------------------------------------------------------------------------- voidcir_sec(processpro[M])//只有柱面号相同的时候才进行旋转调度,定义一个进程pro[M],里面最多存放100个进程 { if(pro[x].rec_num min_rec=8-(record-pro[x].rec_num);//假设现在进程的里面的记录号是5,当前的记录号是4,则移动到记录号4的距离是8-(5-4)=7 else min_rec=pro[x].rec_num-record;//假设现在进程的里面的记录号是5,当前的记录号是7,则移动到记录号7的距离是7-5=2 if(min_rec<=min_r)//首选移动距离最小 { min_r=min_rec;//选择移动距离最小的请求 choosen=x;//选择第X个进程 } } //-------------------------------------------------------******移臂调度*****--------------------------------------------------------------------------------------------- voidmov_sec(processpro[M])//移臂调度 { intcount_abo=0;//大于当前柱面号的进程数 intcount_low=0;//小于当前柱面号的进程数 if(dir==0)//如果方向向里,由小到大,比当前的柱面号大----------------------------*******方向向里*****---------------------------- { for(x=0;x { if(pro[x].signal==1)//判断某个进程是否已经进入I/O请求表 { if(pro[x].cyl_num>cylinder)//如果进程的柱面号大于当前柱面号 count_abo++; } } if(count_abo>0)//有进程柱面号大于当前柱面号 { for(x=0;x { if(pro[x].signal==1)//判断某个进程是否已经进入I/O请求表 { if(pro[x].cyl_num>cylinder&&pro[x].cyl_num { max_min_cyl=pro[x].cyl_num;//继续寻找下一个柱面号,把柱面号小的赋值给max_min_cyl choosen=x;//选择第x个进程 } } } for(x=0;x
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 驱动 调度 完整版 绝对 验收 最高分 注释 详细
![提示](https://static.bdocx.com/images/bang_tan.gif)