1、时间片轮转强占式短进程优先算法学 号: 课 程 设 计题 目进程调度模拟设计时间片轮转、强占式短进程优先算法学 院计算机科学与技术学院专 业班 级姓 名指导教师吴利军2013年1月16日课程设计任务书学生姓名: 指导教师:吴利军 工作单位: 计算机科学与技术学院 题 目: 进程调度模拟设计时间片轮转、强占式短进程优先算法 初始条件:1预备内容:阅读操作系统的处理机管理章节内容,对进程调度的功能以及进程调度算法有深入的理解。2实践准备:掌握一种计算机高级语言的使用。要求完成的主要任务: (包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1模拟进程调度,能够处理以下的情形: 能够选择不同
2、的调度算法(要求中给出的调度算法); 能够输入进程的基本信息,如进程名、到达时间和运行时间等; 根据选择的调度算法显示进程调度队列; 根据选择的调度算法计算平均周转时间和平均带权周转时间。2设计报告内容应说明: 需求分析; 功能设计(数据结构及模块说明); 开发平台及源程序的主要部分; 测试用例,运行结果与运行情况分析; 自我评价与总结:)你认为你完成的设计哪些地方做得比较好或比较出色;)什么地方做得不太好,以后如何改正;)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);)完成本题是否有其他方法(如果有,简要说明该方法);时间安排:设计安排一周:周1、周2:完成程序分析及设计。周2
3、、周3:完成程序调试及测试。周4、周5:验收、撰写课程设计报告。(注意事项:严禁抄袭,一旦发现,一律按0分记)指导教师签名: 年 月 日系主任(或责任教师)签名: 年 月 日进程调度模拟设计时间片轮转、强占式短进程优先算法一、需求分析本次课程设计需要通过设计一个模拟进程调度的系统,来实现进程调度过程的模拟,对进程调度的功能以及进程调度的算法有更加深层次的理解。时间片轮转法的基本思路是每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的就是维护
4、一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。这样让每个进程在就绪队列中的等待时间与享受服务的时间成正比例。在批处理为主的系统中,如果采用FCFS方式进程作业调度,虽然系统开销小,算法简单,但是,如果估计执行时间很短的作业时在那些长作业的后面到达系统的话,则必须等待长作业执行完成之后才有机会获得执行。这将造成不必要的等待和不公平,最短作业优先法就是选择那些估计需要执行时间最短的作业投入执行,为它们创建进程和分配资源。直观上说,采用最短作业优先的调度算法,可使得系统在同一时间内处理的作业个数最多,从而吞吐量也就大于其它调度方式。按照需求有以下条件:进程PCB(包含进程名、到达时间
5、、预计运行时间等)调度算法(时间片轮转、强占式短进程优先)为完成这两种算法的调度模拟,需要用高级语言编程完成模拟操作,能够处理以下的情形:(1)能够选择不同的调度算法(要求中给出的调度算法)(2)能够输入进程的基本信息,如进程名、到达时间和运行时间等(3)根据选择的调度算法显示进程调度队列(4)根据选择的调度算法计算平均周转时间和平均带权周转时间该设计中的进程调度模拟系统在使用时,用户可以输入各进程信息(包含进程名、到达时间、估计运行时间);输入完毕确认后,可选择两种调度算法中的一种执行,查看结果可得到相应算法的调度序列,每个进程的到达时间、预计运行时间、开始时间、结束时间和周转时间、带权周转
6、时间,以及平均周转时间和平均带权周转时间。二、功能设计2.1 进程信息的描述和实现此次课程设计中,进程作为基本数据处理单元,需要对进程的基本信息进行相关的描述。进程的基本信息包括进程进程名、到达的时间、预计的进程运行时间、进程开始运行时间、进程仍需运行的时间、进程完成的时间、进程运行的次数等。在此,定义一个类来抽象进程。并在此基础上进行其他操作。数据结构方案声明如下: class ProcePcb public : ProcePcb (string name,int sub,int exe,int id) : pro_name(name),time_submit(sub),time_exe(e
7、xe),pro_id(id), time_start(0),time_end(0),time_wait(0),pro_state(READY),time_left(exe), time_turn(0),time_aver(0.0) /默认构造函数 ProcePcb () : pro_name (string( ), time_submit(0),time_exe(0),pro_id(-1), time_end(0),time_start(0),time_wait(0),pro_state(READY),time_left(0), time_turn(0),time_aver(0.0) /Get
8、ters and Setters string getPro_name () return pro_name ; int getTime_submit () return time_submit ; int getTime_exe () return time_exe ; int getPro_id () return pro_id ; int getTime_start () return time_start ; int getTime_wait () return time_start ; int getPro_state () return pro_state ; int getTim
9、e_left () return time_left ; int getTime_turn () return time_turn ; int getTime_aver () return time_aver ; void setTime_start (int start) time_start = start ; /设置开始时间 void setTime_left (int left) time_left = left ; void setTime_end (int end) time_end = end ; /设置结束时间 void setPro_state (int state) pro
10、_state = state ; /设置进程的状态 /.打印进程的信息 void PrintPcbInfo () ; / /.进程执行模拟 bool ProceExe(int) ; /参数为时间单位,返回CPU是否执行完毕 /内部逻辑计算 包括周转时间以及带权周转时间的计算 void CalTimeLogic() ;protected: /进程的名字 string pro_name ; /提交时间-用十进制封装 int time_submit ; /从时间的1开始计时 /进程所需的运行时间 int time_exe ; /进程ID - 系统生成 int pro_id ; /开始执行的时间 in
11、t time_start ; /结束的时间 int time_end ; /等待的时间 int time_wait ; /进程的状态 (就绪,执行,完成) int pro_state ; /.上下文封装 int time_left ; /还需多少时间单位,初始化为所需的执行时间/周转时间 int time_turn ; /带权周转时间 float time_aver ; ; 2.2 调度算法的描述和实现进程基本信息所构成的模块作为基本单元,并且相关调度算法的侧重进程基本信息点不同,所以要根据其调度算法的特点来结合基本信息进行对应的设计。此次课程设计要求的调度算法描述如下:2.2.1 时间片轮转
12、调度算法时间片轮转法的中心思想在于将CPU的运行划分为一个个时间片,然后将这些时间片平均分配给已经准备就绪的进程,在一个时间片内只允许一个进程占用处理器。如果当前进程运行结束则时间片终止。这样可以较公平的分配处理器运行时间,使每个进程都可以得到处理。2.2.2 强占式短进程优先调度算法对强占式短进程优先调度算法而言,其本质特征便是按进程的预计运行时间长短进行排序,先执行短进程。若内存中运行的进程优先级比就绪队列中的某进程优先级低(即运行的进程预计运行时间比就绪队列中的某进程长),此运行的进程让出内存并进入就绪队列,优先级更高的短进程强占内存资源并运行直到结束或者遇到优先级更高的进程强占为止。2
13、.2.3 模块说明:class CPUModel /CPU功能模块的封装public : CPUModel () :pcbnum(0),idCount(0),allturn(0),allaver(0.0) /从用户界面获取进程 void GetPcb (pcbList &) ; /.CPU开始执行程序 void ExeProce(pcbList &) ; /时间片轮转法模拟程序 void RRModel(pcbList&) ; /不能改变原队列 /抢占式短进程优先 void SJF_Grab(sjfList) ; /.获取当前时刻之前的最短进程在队列中的标号 int GetTheSP(sjfL
14、ist ,int) ; /队列为排序之后的队列 /.获取下一个进程ID int GetNextId() ; /打印就绪队列中的进程的信息 void PrintList(pcbList) ; int getPcbnum () return pcbnum ; /. bool IsProComing(int) ; /.当前时刻时是否有新的进程到达 /.将就绪队列按提交时间排序 void SortTheList(sjfList) ; bool IsOver(sjfList) ; /是否所有的进程都执行完毕private : /进程数量 int pcbnum ; int idCount ; /进程ID计
15、数 int allturn ; /总周转时间 float allaver ; /总带权周转时间 ;下面为较为重要的几个函数:void ProcePcb:PrintPcbInfo () /打印信息void ProcePcb:CalTimeLogic() /内部逻辑计算bool ProcePcb:ProceExe(int time) /进程执行模拟void CPUModel:GetPcb (pcbList & list) /获取用户需要建立的进程,入就绪队列void CPUModel:PrintList(pcbList list) /打印就绪队列中的进程的信息void CPUModel:ExePr
16、oce (pcbList & list) 进程调度主过程void CPUModel:RRModel(pcbList & list) /时间片轮转法模拟void CPUModel:SJF_Grab(sjfList list) /强占式短进程优先模拟程序的主程序流程如下:int main () CPUModel cpu ; cpu.GetPcb(pcblist) ; cpu.PrintList(pcblist) ; cpu.ExeProce(pcblist) ; return 0 ;三、开发平台Microsoft Windows 7操作系统;Microsoft Visual 2010。四、源程序的
17、主要部分4.1. 时间片轮转法模拟部分:void CPUModel:RRModel(pcbList & list) static int rtime = 1 ; /表示时钟 if(list.size() = 0) return ; /.不断的从就绪队列中取进程执行 /* 时间片轮转的模型是: 时间片为1秒 进程各个时间都以十进制来简化 进程正在执行时打印其信息并让主CPU停顿1秒以表示执行进程一个时间单位 */ ProcePcb pcb ; /每次执行的进程 /设置一个轮转队列 pcbList rrlist ; while (1) /查找当前时间下已经提交的进程入轮转队列 if(IsProCo
18、ming(rtime) while(readylist.size() != 0 & IsProComing(rtime + 1) /先对队列判空是必须的 ProcePcb pcb = readylist.front() ; rrlist.push(pcb) ; readylist.pop() ; /下面的程序操作轮转队列 if(rrlist.size() = 0 ) /查看最早提交的进程 cout TIME: 第 rtime 秒:endl ; cout 没有进程提交!endl ; +rtime ; Sleep(1000) ; /消耗CPU时间1秒 continue ; /. /.每次从队列中取
19、第一个进程 pcb = rrlist.front() ; rrlist.pop() ; /先进行进程逻辑维护 pcb.setPro_state(EXECUTE) ; /设置执行状态 if(pcb.getTime_start() = 0) pcb.setTime_start(rtime) ; /设置开始时间 bool result = false ; result = pcb.ProceExe(1) ; /进程执行一个时间单位 cout TIME: 第 rtime 秒:endl ; cout正在调度执行的进程:endl; pcb.PrintPcbInfo() ; /打印正在执行的进程的信息 if
20、(result) /进程执行完毕 pcb.setPro_state(END) ; pcb.setTime_end(rtime) ; /结束的时间 /CPU调度统计计算 pcb.CalTimeLogic() ; allturn += pcb.getTime_turn() ; allaver += pcb.getTime_aver() ; /. cout进程:endl ; pcb.PrintPcbInfo() ; cout执行完毕endl ; else /执行完一个时间片后进程仍然没有完毕 /则要查看下一个进程是否已经提交. 现在设置了轮转队列不要进行这个判断 pcb.setPro_state(R
21、EADY) ;/设置进程的状态为就绪 rrlist.push(pcb) ; /入轮转队列 if(rrlist.size() = 0 & readylist.size() = 0) /所有进程调度执行完毕 cout TIME: 第 rtime 秒:endl ; cout所有的进程执行完毕,退出时间片轮转法模拟模块程序!endl ; cout轮转法调度结果统计:endl ; cout 总进程数:pcbnum 个 endl ; cout 平均周转时间 : (float)allturn/pcbnumendl ; cout 平均带权周转时间 : allaver/pcbnumendl ; coutendl
22、 ; break ; +rtime ; Sleep(2000) ; /消耗CPU时间1秒4.2强占式短进程优先法部分:void CPUModel:SJF_Grab(sjfList list) if(list = NULL ) return ; static int time = 1 ; /控制CPU的时钟从1开始计时 int pid = -1; /选取占有CPU的进程在队列中的位置 /. while(1) pid = GetTheSP(list,time) ; /获取已经提交的进程中最短进程 /进程尚未结束但是返回-1则说明当前时间还没有提交任何进程 if(!IsOver(list) & pi
23、d = -1) cout TIME: 第 time 秒:endl ; cout 没有进程提交!endl ; +time ; Sleep(1000) ; /消耗CPU时间1秒 continue ; else if(!IsOver(list) & pid != -1) /执行进程 /先进行进程逻辑维护 listpid.setPro_state(EXECUTE) ; /设置执行状态 if(listpid.getTime_start() = 0) listpid.setTime_start(time) ; /设置开始时间 bool result = false ; result = listpid.P
24、roceExe(1) ; /进程执行一个时间单位 cout TIME: 第 time 秒:endl ; cout正在调度执行的进程:endl; listpid.PrintPcbInfo() ; /打印正在执行的进程的信息 if(result) /进程执行完毕 listpid.setPro_state(END) ; listpid.setTime_end(time) ; /结束的时间 /CPU调度统计计算 listpid.CalTimeLogic() ; allturn += listpid.getTime_turn() ; allaver += listpid.getTime_aver() ;
25、 /. cout进程:endl ; listpid.PrintPcbInfo() ; cout执行完毕endl ; +time ; Sleep(1000) ; /消耗CPU时间1秒 else if(IsOver(list) /所有的进程执行完毕 cout TIME: 第 time 秒:endl ; cout所有的进程执行完毕,退出强占式短进程优先法模拟程序!endl ; cout强占式短进程优先法调度结果统计:endl ; cout 总进程数:pcbnum 个 endl ; cout 平均周转时间 : (float)allturn/pcbnumendl ; cout 平均带权周转时间 : al
26、laver/pcbnumendl ; coutendl ; break ;五、测试用例进程名:a 到达时间:1 预测运行时间:3进程名:b 到达时间:3 预测运行时间:5进程名:c 到达时间:5 预测运行时间:2依次输入进程信息。输入完毕后可显示出所有进程信息,并可开始选择使用哪种算法进行模拟调度,下面选择1,时间片轮转法,模拟开始。3秒末进程a 执行完毕,显示其周转时间和带权周转时间。10秒末进程c执行完毕,显示其周转时间和带权周转时间。11秒末进程b执行完毕,显示其周转时间和带权周转时间。所有调度完毕,显示平均周转时间和平均带权周转时间。继续选择2,模拟强占式短进程优先3秒末进程a 执行完
27、毕,显示其周转时间和带权周转时间。7秒末进程c执行完毕,显示其周转时间和带权周转时间。11秒末进程b执行完毕,显示其周转时间和带权周转时间。所有调度完毕,显示平均周转时间和平均带权周转时间。六、自我评价与总结1. 优势:该程序封装性好,用了几个类进行封装,程序的结构非常清晰,每一个功能都用一个模块来实现,方便以后的移植。在进程调度开始之前显示打印出每个进程的信息供输入者检查可以避免不必要的错误和误操作,在调度模拟过程中,每一秒的进程调度情况都打印出来供程序操作者参考,调度过程显得十分直观,充分反应了编程模拟的优越性。2不足:我在定义数据结构时考虑还不太周全,我把时间都定义成了int型,就意味着
28、我不能处理毫秒级别的问题,而且程序到达时间的输入不能和实际的世界时刻进行同步,只能做比较简单的调度模拟。处理时间片轮转法时我将时间片固定了,并不能根据具体的情况来变化时间片的长度。意味着如果需要处理的进程的运行时间都很长的话,会浪费比较多的系统资源来轮转处理器的执行。3总结: 通过这次设计,我更加深刻的理解了2种调度算法之间的共同点、差别、以及在不同情况下的优劣。锻炼了我运用c+高级编程语言的能力,可以运用编程语言进行对操作系统调度算法的模拟,更直观的感受了操作系统内部的调度是如何运行如何分配系统资源的。课程设计是联系实际的一个课题,它让我们把课本上的知识和实战演练联系起来,对于我们缺乏实际编程经验的大学生来说是必不可少的。本科生课程设计成绩评定表 序号评分项目满分实得分1学习态度认真、遵守纪律102设计分析合理
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1