进程调度算法.docx
- 文档编号:24957179
- 上传时间:2023-06-03
- 格式:DOCX
- 页数:42
- 大小:416.99KB
进程调度算法.docx
《进程调度算法.docx》由会员分享,可在线阅读,更多相关《进程调度算法.docx(42页珍藏版)》请在冰豆网上搜索。
进程调度算法
目录
一、课程设计任务描述1
1、设计目的1
2、设计要求1
3、设计内容1
二、问题定义与需求分析2
1、问题定义2
1.1、相关知识2
1.2、设计原理2
1.3、设计构想2
2、需求分析3
三、概要设计及流程图3
1、类定义3
2、建立输出表格并对表格进行初始化3
3、流程图4
四、问题实现及代码6
1、函数定义6
2、函数变量定义7
3、初始化界面7
4、界面效果8
5、模块核心代码9
五、调试分析12
六、测试13
1、先来先服务调度13
2、短作业优先调度13
3、时间片轮转调度14
4、高优先权调度14
5、高响应比优先权调度15
七、结论15
八、参考文献16
附录17
1、使用说明书17
2、源程序Unit1.h代码17
3、源程序Unit1.cpp代码20
一、课程设计任务描述
1、设计目的
《操作系统》是一门重要的专业基础课,在计算机软硬件课程的设置上,它起着承上启下的作用。
操作系统对计算机系统资源实施管理,是所有其他软件与计算机硬件的唯一接口,所有用户在使用计算机时都要得到操作系统提供的服务。
操作系统的核心概念和主要算法的掌握。
操作系统课程设计的主要任务是强化学生对本课程基础知识的掌握;加深学生对操作系统的基本概念、工作原理和典型算法的理解;使学生对系统的组织和运作机制有一个较全面的认识;提高学生通过编程求解问题的能力;巩固和加强与本课程相关的其他计算机课程的知识,提高对计算机专业知识理解的系统性和完整性。
2、设计要求
(1)用高级语言编写和调试实现不用作业/进程调度算法的程序。
(2)运用《操作系统》课程中所涉及的基本原理或《数据结构》相关知识实现可视化界面程序。
3、设计内容
熟悉各种作业/进程调度算法原理。
该题目实现对调度算法的模拟,分为5个子题目:
1)先来先服务调度算法;
2)短作业/进程优先调度算法;
3)高优先权调度算法;
4)高响应比优先算法;
5)基于时间片的轮转调度算法;
由用户输入等待调度的作业信息,选择调度算法,显示出根据相应算法进行调度的运行结果。
二、问题定义与需求分析
1、问题定义
1.1、相关知识
进程:
进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。
运行状态:
进程正在处理器上运行。
就绪状态:
一个进程获得了除处理器外的一切所需资源,一旦得到处理器即可运行。
等待状态:
一个进程正在等待某一事件发生而暂时停止运行。
结束时间:
进程开始执行时间+进程服务时间。
周转时间:
进程结束时间-进程到达时间。
带权周转时间:
周转时间/服务时间。
1.2、设计原理
(1)先来先服务调度:
最先到达的进程先进行调度。
(2)短作业优先调度:
从已到达的进程中选出最短的进程优先调度。
(3)时间片轮转调度:
每个进程依次的按时间片轮转的方式执行。
(4)静态优先权调度:
赋予优先权,在已到达的进程中选出优先权最高的优先调度。
(5)高响应比优先调度:
优先权随等待时间而增加,从而使等待时间较长且服务时间较短的进程优先服务。
(响应比=1+等待时间/服务时间)
1.3、设计构想
程序能够完成以下操作:
(1)用户可以选择调度方法;
(2)用户可以创建进程:
输入每个进程包括进程名、开始执行时间、服务时间、优先数、时间片等;
(3)用户界面上要打印出各个进程的信息;
(4)用户运行后要在界面上显示:
进程开始执行时间、完成时间、周转时间、带权周转时间、平均周转时间、调度结果等,以便用户对调度整个过程有一个清除的理解。
(5)用户可以对已输入的数据进行清除;
2、需求分析
在多道程序环境下,主存中有着多个进程,其数目往往多于处理机数目,要使这多个进程能够并发地执行,这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之执行。
分配处理机的任务是由处理机调度程序完成的。
由于处理机是最重要的计算机资源,提高处理机的利用率及改善系统必(吞吐量、响应时间),在很大程度上取决于处理机调度性能的好坏,因而,处理机调度便成为操作系统设计的中心问题之一。
本次课设在C++Builder6环境下实现先来先服务调度算法,短作业优先调度算法,高优先权调度算法,时间片轮转调度算法和高响应比优先算法。
三、概要设计及流程图
1、类定义
采用单一继承的方式继承新的ClassTForm类,拥有TFrom类的所有公有部分,包括各个按钮的属性,标签属性以及输入框函数。
并在头文件中显示该程序所包含的所有应用属性。
2、建立输出表格并对表格进行初始化
在C++Builder中选择Additional按钮,在菜单选项中选择StringGird,建立表格。
可以在表格的选项卡中选择表格行数和列数。
双击StringGird并对其进行初始化:
__fastcallTFrom:
:
TFrom(TComponent*Owner)//初始化表格
:
TForm(Owner)
{}
3、流程图
图1程序设计流程图
图1所示流程图是本次课设顺利完成的关键,是该程序的核心。
图2先来先服务流程图
图2所示流程图是本算法的核心是先到达的进程最先调度
图3优先权调度算法
图3为优先权调度算法按进程的执行顺序由高优先级到低优先级,优先权高的最先运行。
图4短作业优先调度
图4短作业优先调度算法是指对短作业进行调度的算法。
它从后备队列总选择一个或若干个运行时间最短的作业,将他们调入内存运行。
图5时间片轮转算法
图5为时间片轮转算法,所有就绪进程按先来先服务的原则排成一个队列,将新来的进程加到就绪对列的末尾,每当执行进程调度时,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。
四、问题实现及代码
1、函数定义
void__fastcallFormCreate(TObject*Sender);
//先来先服务调度
void__fastcallButton1Click(TObject*Sender);//添加进程
void__fastcallButton2Click(TObject*Sender);//运行按钮
void__fastcallButton3Click(TObject*Sender);//清除按钮
//短作业优先调度
void__fastcallButton4Click(TObject*Sender);//添加进程
void__fastcallButton6Click(TObject*Sender);//运行按钮
void__fastcallButton5Click(TObject*Sender);//清除按钮
//时间片轮转调度
void__fastcallButton7Click(TObject*Sender);//添加进程
void__fastcallButton9Click(TObject*Sender);//运行按钮
void__fastcallButton8Click(TObject*Sender);//清除按钮
//高优先权调度
void__fastcallButton10Click(TObject*Sender);//添加进程
void__fastcallButton12Click(TObject*Sender);//运行按钮
void__fastcallButton11Click(TObject*Sender);//清除按钮
//高响应比优先权调度
void__fastcallButton13Click(TObject*Sender);//添加进程
void__fastcallButton14Click(TObject*Sender);//运行按钮
void__fastcallButton15Click(TObject*Sender);//清除按钮
2、函数变量定义
#pragmapackage(smart_init)
#pragmaresource"*.dfm"
TFrom*From;
floatsuper[6];//优先权
floatcome[6];//到达时间
floatserve[6];//服务时间
floatbegin[6];//开始执行时间
floatend[6];//完成时间
floatall[6];//周转时间
floatdall[6];//带权周转时间
floatmax(float,float,float);
3、初始化界面
//---------------------------------------------------------------
__fastcallTFrom:
:
TFrom(TComponent*Owner)//初始化表格
:
TForm(Owner)
{}
//---------------------------------------------------------------
void__fastcallTFrom:
:
FormCreate(TObject*Sender)
{sgr->Cells[0][0]="进程名";sgr1->Cells[0][0]="进程名";
sgr2->Cells[0][0]="进程名";sgr3->Cells[0][0]="进程名";
sgr4->Cells[0][0]="进程名";sgr3->Cells[0][1]="优先权";
sgr->Cells[0][1]="到达时间";sgr1->Cells[0][1]="到达时间";
sgr2->Cells[0][1]="到达时间";sgr3->Cells[0][2]="到达时间";
sgr4->Cells[0][1]="到达时间";sgr->Cells[0][2]="服务时间";
sgr1->Cells[0][2]="服务时间";sgr2->Cells[0][2]="服务时间";
sgr3->Cells[0][3]="服务时间";sgr4->Cells[0][2]="服务时间";
sgr->Cells[0][3]="开始时间";sgr1->Cells[0][3]="开始时间";
sgr3->Cells[0][4]="开始时间";sgr4->Cells[0][3]="开始时间";
sgr4->Cells[0][4]="等待时间";sgr4->Cells[0][5]="响应比";
sgr->Cells[0][4]="完成时间";sgr1->Cells[0][4]="完成时间";
sgr2->Cells[0][3]="完成时间";sgr3->Cells[0][5]="完成时间";
sgr4->Cells[0][6]="完成时间";sgr->Cells[0][5]="周转时间";
sgr1->Cells[0][5]="周转时间";sgr2->Cells[0][4]="周转时间";
sgr3->Cells[0][6]="周转时间";sgr4->Cells[0][7]="周转时间";
sgr->Cells[0][6]="带权时间";sgr1->Cells[0][6]="带权时间";
sgr2->Cells[0][5]="带权时间";sgr3->Cells[0][7]="带权时间";
sgr4->Cells[0][8]="带权时间";sgr->Cells[0][7]="调度结果";
sgr1->Cells[0][7]="调度结果";sgr3->Cells[0][8]="调度结果";
sgr4->Cells[0][9]="调度结果";
}
4、界面效果
图6运行初始化界面
5、模块核心代码
5、1先来先服务调度
for(i=2;i<=5;i++)
{
begin[i]=max(serve[i-1],begin[i-1],come[i]);//调用函数
sgr->Cells[i][3]=begin[i];
}//开始时间
for(i=1;i<=5;i++)//计算各值
{
end[i]=begin[i]+serve[i];//完成时间
sgr->Cells[i][4]=end[i];
all[i]=end[i]-come[i];//周转时间
sgr->Cells[i][5]=all[i];
dall[i]=all[i]/serve[i];//带权周转时间
sgr->Cells[i][6]=dall[i];
a=a+all[i];
sgr->Cells[i][7]=i;
}
5、2短作业优先调度
for(j=1;j<=4;j++)
{
index++;//index自动指向下一进程
if(index>5)//index复位
{for(k=2;k<=5;k++)
if(flag[k]==1)
{index=k;//index指向第一个未执行的进程
break;
}
}
for(i=2;i<=5;i++)
{//满足三个条件1、已到达2、未调度过3、服务时间最小
if((come[i]<=end[run])&&(serve[index]>serve[i])&&(flag[i]==1))
{
index=i;
}
elseif(come[i]>end[run])
//如果进程完成但未有进程到达,则下一进程来到即可运行
break;
}
flag[index]=0;
//处理index,index为当前运行进程编号,run为上一进程编号
begin[index]=max(serve[run],begin[run],come[index]);
sgr1->Cells[index][3]=FloatToStr(begin[index]);//打印开始进程时间
run=index;
end[index]=begin[index]+serve[index];//计算完成时间
sgr1->Cells[index][4]=FloatToStr(end[index]);
all[index]=end[index]-come[index];//计算周转时间
sgr1->Cells[index][5]=FloatToStr(all[index]);
a=a+all[index];sgr1->Cells[index][6]=FloatToStr(all[index]/serve[index]);//计算并打印带权周转时间
t[j]=index;//t[j]为调度序列
}
5、3时间片轮转调度
for(j=1;j<=100;j++)//设置总时间片不超过100
{for(i=1;i<=5;i++)
{if(flag[i]==1)
{serve[i]-=q;//计算服务时间
if(serve[i]>0)
{t+=q;}//t为当前执行的总时间
elseif(serve[i]<=0)
{t+=(q+serve[i]);//t为当前执行的总时间
end[i]=t;//进程调度完毕完成时间
flag[i]=0;//一旦进程被调度flag值为0
}
}
}
}
5、4优先权调度
for(j=1;j<=4;j++)
{
index++;
while(flag[index]==0)
{index++;}//index指向下一个待运行的进程
if(index>5)//index的复位
{for(k=2;k<=5;k++)
if(flag[k]==1)
{index=k;
break;
}
}
for(i=2;i<=5;i++)
{
if((come[i]<=end[run])&&(super[index]>super[i])&&(flag[i]==1))
{
index=i;//满足条件的进程送至index
}
elseif(come[i]>end[run])
break;
}
5、5高响应比优先权调度
for(j=1;j<=4;j++)
{
index++;
if(index>5)
{for(k=2;k<=5;k++)
if(flag[k]==1)
{index=k;
break;
}
}
for(i=2;i<=5;i++)
{
if((come[i] &&(flag[i]==1))//动态计算响应比并比较 { index=i; } elseif(come[i]>end[run]) break; } 五、调试分析 本程序使用的C++Builder编译器,一开始调试时出现很多错误,提示错误也不像VC那样能具体找到哪一行,所以一开始很迷茫。 后来通过一个个提示的错误在网上寻找错误原因,试着一步步修改,慢慢的调试,最终错误慢慢的减少。 可是对有些函数的定义以及用法还不是明白,在网上搜到的说法又是多种多样的,还好在网上找到了C++Builder6.0Programming这本书,仔细的阅读和查阅,在其中发现了不少函数的定义,以及对Builder软件的介绍。 后来在网上找到了一些视频,虽然是外文小语种讲的(确实听不懂讲的是什么),但通过视频演示对我的帮助深大。 六、测试 1、先来先服务调度 图7先来先服务调度测试 分析: 先来先服务算法比较有利于长作业(进程),而不利于短作业(进程)。 因为短作业运行时间很短,如果让它等待较长时间才得到服务,那么,它的带权周转时间就会很高;先来先服务调度算法有利于CPU繁忙型的作业,不利于I/O繁忙型的作业,而目前大多数事务处理都属于I/O繁忙型作业。 2、短作业优先调度 图8短作业优先调度算法测试 分析: .短作业优先调度算法能有效地降低作业的平均等待时间,提高系统吞吐量。 然而该算法对长作业不利,因为调度程序总是优先调度那些短作业,将导致长作业长期不被调度,该算法完全未考虑作业的紧迫程度,因而不能保证紧迫性作业会被及时处理,由于作业的长短只是根据用户提供的估计执行时间而定的,而用户又可能有意无意地缩短其作业的估计运行时间,致使该算法不能真正做到短作业优先调度; 3、时间片轮转调度 图9时间片轮转调度算法测试 分析: 时间片轮转算法则算是对每个进程都是公平的,减少了进程的等待时间,但是时间片设得太短会导致过多的进程切换,降低了CPU效率;而设得太长又可能引起对短的交互请求的响应变差。 将时间片设为100毫秒通常是一个比较合理的折衷; 4、高优先权调度 图10高优先权调度算法测试 分析: 高优先级调度算法则保证了紧迫进程,而那些优先级较低的则可能长时间得不到调度;静态优先级调度算法简单易行,系统开销小,但是不太灵活,很可能出现低优先级的作业,长期得不到调度而等待的情况;静态优先级法仅适合于实现要求不太高的系统。 动态优先级调度算法比较灵活科学,可防止有一些进程一直得不到调度,也可防止有些进程长期垄断处理机,但是需要花费相当多的执行程序时间,因而花费的系统开销比较大。 5、高响应比优先权调度 图11高响应比优先权调度算法测试 分析: 高响应比优先调度是对FCFS和SJF方法的一种综合平衡,高响应比优先调度策略同时考虑每个作业的等待时间长短和评估需要的执行时间长短,从中选出响应比较高的作业进行执行。 由于每次要计算响应比,系统开销相应增加。 七、结论 这次课程设计是运用已经学过的操作系统知识对先来先服务算法、短作业优先算法、时间片轮转算法、高优先权算法、高响应比优先算法进行设计,使我在对进程的调度算法有充分的理解的同时,也使我的实践编程能力和运用理论知识的能力得到了进一步的提升。 此次课设花了一周多的时间完成了程序的编写和界面的设计,这其中也走了不少弯路,一开始,没有使用表格和PageControl,而是使用了几百个Edit和Form大大的增加了管理的难度,同时使Unit.h文件很长,多大十几页,后来在网上看视频了解了表格,有用表格做了调整。 我认为这次课程设计自己比较出色的一点是自己一开始就有了一整套的思路,不像以前的课程设计那样,对全局的规划不是很清楚,以至于在后来的衔接做的不到位,但是此次设计由于初始就对各个功能模块的相互调用也比较了解,所以对课设的设计整体上比较轻松,也使程序的编写比较清晰。 在设计中,我也碰到了不少问题,主要是对C++Builder6还不是熟悉,有很多工具还不会用。 有一些还不会设置,本来准备用Timer定时器控制到达时间和等待时间的,动态显示结果,不过,因为不熟悉,所以没能实现,如果那样做会更完美一些。 在高响应比优先权调度算法中响应比的计算应该是动态的,每有一进程执行则后面没有运行的进程都要计算响应比,但由于考虑到界面美观,所以本程序只把每次计算的响应比最高的一个进程的响应比进行界面显示,如果能够动态的打印出所有动态响应比进行比较那样效果会更直观。 执行过程周,当使用“清除”按钮后再点击“运行”按钮。 仍然显示运行结果,后来经过老师的指导,使用了Button按钮的Enabled属性改为False,最终问得到了解决。 这次设计,我对于C语言的各种用法也重新温习了一下,不过,我使用了数组,麻烦一些,如果使用结构体,会更方便,更好一些。 八、参考文献 [1]汤小丹,梁红兵,哲凤屏,汤子赢.计算机操作系统[M].西安: 西安电子科技大学出版社,2007.5第3版 [2]吴跃.数据结构与算法[M].北京: 机械工业出版社,2010.2 [3]陆卫忠,刘文亮.C++Builder6.0[M].北京: 科学出版社,2011.4.1 [4]赵明现,C++Builder6编程实例精解[M].北京: 机械工业出版社,2004.2 附录 1使用说明书 本程序采用C++Builder6编程和设计界面 考虑到调度算法较多,采用了多页面的界面,加入的进程限制五个,在文本框中模拟到达一进进程后,输入到达时间和服务时间,点击“加入新进程”即可,输入完成之后,点击“运行”即可得到表中各值。 想从新输入点击“清除”按钮。 关闭时请直接点击“X”即可 2源程序Unit1.h代码 //--------------------------------------------------------------- #ifndefUnit1H #defineUnit1H //--------------------------------------------------------------- #include #include #include #include #include #i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 进程 调度 算法
![提示](https://static.bdocx.com/images/bang_tan.gif)