操作系统课程设计报告进程作业调度.docx
- 文档编号:24208024
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:47
- 大小:37.98KB
操作系统课程设计报告进程作业调度.docx
《操作系统课程设计报告进程作业调度.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告进程作业调度.docx(47页珍藏版)》请在冰豆网上搜索。
操作系统课程设计报告进程作业调度
、课程设计题目:
进程/作业调度
二、实现要求:
1.建立作业的数据结构描述
2.使用两种方式产生作业/进程:
(a)自动产生(b)手工输入
3.在屏幕上显示每个作业/进程的执行情况。
4.时间的流逝可用下面几种方法模拟:
(a)按键盘,每按一次可以认为过一个时间单位(b)响应WM_TIMER(本实验采用b方法)
5.计算并显示一批作业/进程的周转时间,平均周转时间,带权周转时间,平均带权周转时间。
6.将一批作业/进程的执行情况存入磁盘文件,以后可以读出并重放。
7.支持的调度算法:
先来先服务,短作业/进程优先,时间片轮转调度算法,优先权调度算法,高响应比优先调度算法,多级反馈队列调度算法。
三、实验设备及环境:
IBMPC及其兼容机一台、WindwosXP操作系统、MicrosoftVisualC++6.0集成开发环境。
四实验目的:
通过本次课程设计进一步加深对进程控制块、进程调度的理解,能够实现各种不同的进程调度算法。
深入理解操作系统设计中有关进程方面的应该注意的相关事项。
五实验总体设计思路:
1、程序结构框架<1>程序中自定义了一个进程控制块PCB结构体,所有对进程的调度、进程切换等操作全都建立在PCB的基础之上。
PCB中保存了进程标识符、进程到达时间、等待时间、进程调度状态、需要运行的时间等重要信息。
PCB的定义如下:
structPCB{
intpid;
intstatus;
intpriority;
intstart_time;
intneed_time;
intwait_time;
intend_time;structPCB*next;
//PCB结构
//ID号
//进程状态
//进程优先级数值越小,优先级越高
//进程开始时间
//进程执行所需时间
//进程已等待时间
//运行结束时间
//PCB指针,指向下一PCB};
<2>程序中还定义了一个正在PCB类型的指针指向正在运行的进程的进程控制块,3个就绪队列。
除了多级反馈队列调度算法需要用到3个就绪队列外其他5种调度算法均只需要一个就绪队列。
<3>本程序实现中采取产生PCB代替真实进程的方法来模拟进程。
<4>本程序采用MFC框架构建,菜单栏主要包括了进程选项与调度算法。
以task单文档视图为主题结构,mainframe实现菜单栏功能。
2、程序初始化阶段
<1>程序开始运行后首先要产生若干个进程,可以采取自动产生也可以采取手工输入进程控制块参数的方法产生进程。
当用户每点击“自动产生”菜单一次,函数voidCMainFrame:
:
。
nAuto()便自动产生一个进程并将其挂到就绪队列末尾,当用户点击“手工输入”菜单,便由函数voidCMainFrame:
:
OnManual()弹出输入对话框引导用户输入进程参数,之后把新产生的进程控制块挂到就绪队列末尾。
以上两个函数均对进程编号pid做检查,以保证每个进程的唯一性,不允许有相同的进程。
<2>在“调度算法”菜单中,用户选择了调度算法后,由相应的消息响应函数对调度算法标志dispatch进行赋值,然后根据dispatch值调用相关函数执行作业(进程)调度运算。
////////////////////调度算法的响应函数///////////////////
voidCMainFrame:
:
OnFcfs(){dispatch=1;}
voidCMainFrame:
:
OnSpf(){dispatch=2;}
voidCMainFrame:
:
OnTimeroll(){dispatch=3;}
voidCMainFrame:
:
OnPriority(){dispatch=4;}
voidCMainFrame:
:
OnHrespond(){dispatch=5;}voidCMainFrame:
:
OnMultifeedback(){dispatch=6;}/////////////////////////////////////////////////////////voidCMainFrame:
:
dispatch_entry()//算法入口{
switch(dispatch)
{
case1:
fcfs();break;
case2:
spf();break;
case3:
timeRoll();break;
case4:
priority();break;
case5:
hirespond();break;
case6:
multiFeedback();
}
}
如果未选择进程调度算法,系统默认使用先来先服务的调度算法(dispatch赋值为1)。
3、运行阶段
<1>用户点击“运行”菜单后消息响应函数voidCMainFrame:
:
OnRun()设置计时器开始计时,置程序状态为运行状态,开始对各进程进行模拟调度、运行。
在模拟进程调度运行的过程中由消息响应函数voidCMainFrame:
:
OnTimer(UINT
nIDEvent)每秒被调用一次,在该函数中对各进程的状态进行刷新(包括进程调度)并输出到屏幕供用户观察进程的调度运行情况。
<2>程序中还有一个free队列,该队列中保存所有运行完的进程的进程控制块,因为这些进程控制块信息要用来计算进程的周转时间,平均周转时间,带权周转时间,平均带权周转时间。
<3>进程运行完后点击“打印运行结果”菜单,由voidCMainFrame:
:
OnPrintresult()函数计算并打印进程的周转时间,平均周转时间,带权周转时间,平均带权周转时间。
<4>重放功能的实现较简单,在调度开始前每产生一个进程便调用void
CMainFrame:
:
store_PCB(constPCB*p)函数把该进程的PCB保存到文件pcb.txt中。
当运行完后只需把文件pcb.txt中保存的PCB按系统时间先后顺序依次读出并挂到就绪队列后按之前的调度算法再开始调度运行便可。
六、主要代码分析
1、进程代码
<1>
/*
voidCMainFrame:
:
OnAuto()函数,自动产生进程控制块(PCB)状态。
产生的
PCB挂接到以存在PCB的后面,其中,为了演示程序,优先级和所需时间都限
定在1-10之内。
*/
voidCMainFrame:
:
OnAuto()
{
//随机数产生srand((unsigned)time(NULL));
//产生新的PCB指针ready_end->next=newPCB();ready_end=ready_end->next;
ready_end->next=NULL;//产生新的PCBready_end->pid=getnewpid();
ready_end->status=0;ready_end->priority=(rand()%9+1);ready_end->start_time=task_timer;ready_end->need_time=(rand()%9+1);
ready_end->wait_time=0;ready_end->end_time=0;
//存储状态到pcb.txtstore_PCB(ready_end);
//进行刷新显示操作
status_print();
}<2>
/*
voidCMainFrame:
:
OnManual()函数,点击菜单栏“手动输入”后手动创建PCB。
*/voidCMainFrame:
:
OnManual()
{
CInputDlginput;
if(input.DoModal()==IDOK){
if(!
exist_pid(input.m_pid)){ready_end->next=newPCB();ready_end=ready_end->next;ready_end->next=NULL;
ready_end->pid=input.m_pid;ready_end->status=0;
ready_end->priority=input.m_priority;ready_end->start_time=task_timer;ready_end->need_time=input.m_needtime;ready_end->wait_time=0;
ready_end->end_time=0;
store_PCB(ready_end);
status_print();
}
elseMessageBox("ID号重复,请重新输入.");
}
}
<3>
/*
调用SetTimer函数,以一秒钟为单位,以定时器TASK_TIMER为标志,使用OnTimer()函数做事件响应。
*/
voidCMainFrame:
:
OnRun()
{
if(app_status==false)
{
SetTimer(TASK_TIMER,1000,NULL);
app_status=true;
}
}
其中,voidCMainFrame:
:
OnTimer(UINTnIDEvent)为关键函数。
在此函数中,确定了
⑴函数判断replay赋值情况,为真调用get_PCB_FromFile()函数,从pcb.txt文件中调用数据。
⑵调用status_print()函数进行显示操作。
【voidCMainFrame:
:
status_print()函数,在创建的矩形框内每隔单位时间(此时间为1秒)进行刷新显示所有可用PCB操作。
】
⑶在第一次运行OnTimer时,系统调用dispatch_entry()进行算法选择,只要用
户选择过算法,dispatch值会做响应改变,dispatch_entry(根据dispatch值进入相应算法。
voidCMainFrame:
:
OnTimer(UINTnIDEvent)
{
if(TASK_TIMER&&app_status==true)
{
task_timer++;if(replay==true)get_PCB_FromFile();add_wait_time();
status_print();dispatch_entry();
}
elsetask_timer=0;CFrameWnd:
:
OnTimer(nIDEvent);
}
【UINTSetTimer(UINTnIDEvent,UINTnElapse,void(CALLBACKEXPORT*lpfnTimer)(HWND,UINT,UINT,DWORD));
参数含义:
nIDEvent:
是指设置这个定时器的iD,即身份标志,这样在OnTimer()事件中,才能根据不同的定时器,来做不同的事件响应。
这个ID是一个无符号的整型。
nElapse是指时间延迟。
单位是毫秒。
这意味着,每隔nElapse毫秒系统调用一次Ontimer()。
】
<4>
周转时间:
是指从作业被提交给系统开始,到作业完成为止的这段时间间隔。
平均周转时间T=1/n[刀T].
带权周转时间W是指作业的周转时间T与系统为它提供服务的时间之比。
平均带权周转时间W=1/n[刀vy.
voidCMainFrame:
:
OnPrintresult()
{
CRectrect;
CFontfont;
HideCaret();
CDC*pDC;
pDC=GetDC();
CBrushbrush;
CPenpen(PS_SOLID,2,RGB(84,141,226));brush.CreateSolidBrush(RGB(84,141,226));pDC->SelectObject(pen);
pDC->SelectObject(brush);
CFont*pOldFont=(CFont*)pDC->SelectObject(&font);pDC->Rectangle(100,40,700,600);
pDC->TextOut(200,80,"PID到达时间服务时间完成时间周转时间带权周转时间");
PCB*p=free->next;
inti=0,s=100;
intturnover,server_time;
floatsum_turn=0,sum_right=0,right=0;
charbuffer[100];
while(p!
=NULL)//输出显示一个队列.
{
//周转时间
turnover=p->end_time-p->start_time;
//带权周转时间
right=turnover/(float)(p->end_time-p->start_time-p->wait_time);server_time=p->end_time-p->start_time-p->wait_time;sprintf(buffer,"%3d%10d%16d%18d%17d%25.3f",p->pid,p->start_time,server_time,p->end_time,turnover,right);
sum_turn+=turnover;
sum_right+=right;
i++;
pDC->TextOut(200,s,buffer);
p=p->next;
s=s+20;
}
//sum_turn/i计算平均周转时间,sum_right/i计算平均带权周转时间sprintf(buffer,"平均周转时间:
%0.3f",sum_turn/i);pDC->TextOut(200,s,buffer);
sprintf(buffer,"平均带权周转时间:
%0.3f",sum_right/i);pDC->TextOut(200,s+20,buffer);
ReleaseDC(pDC);
ShowCaret();
}
<4>
//释放所有PCB占用空间
voidCMainFrame:
:
OnRelease().
{
PCB*p;
while(free->next!
=NULL){
p=free->next;
free->next=p->next;
deletep;
}
free_end=free;
MessageBox(‘释放成功”);
}
<4>
赋值replay为true,调用OnRun()函数,进行进程显示操作。
具体在OnTimer()
函数中已经说明
voidCMainFrame:
:
OnPlayback()
{
if(replay==false){
replay=true;
OnRun();
}
}
2、具体算法函数
<1>每个具体算法函数对应一个dispatch值。
voidCMainFrame:
:
OnFcfs(){dispatch=1;}
voidCMainFrame:
:
OnSpf(){dispatch=2;}
voidCMainFrame:
:
OnTimeroll(){dispatch=3;}
voidCMainFrame:
:
OnPriority(){dispatch=4;}
voidCMainFrame:
:
OnHrespond(){dispatch=5;}
voidCMainFrame:
:
OnMultifeedback(){dispatch=6;}
<2>先来先服务调度算法(FCFS)。
按照先来先服务调度算法定义,依次执行队列中PCB。
通过task_run()函数是从PCB队列中取出一个最靠前的PCB指针,处理完成后使用pcb_recycle()函数释放run指针空间;再继续使用task_run()函数……依次反复直到队列结束。
voidCMainFrame:
:
fcfs()
{
if(run!
=NULL||ready->next!
=NULL||blocked->next!
=NULL){
task_run();
if(run!
=NULL){
run->need_time--;
if(run->need_time==0){
pcb_recycle();
task_run();
if(run!
=NULL)run->wait_time++;
}
}
}
elseapp_status=false;
}
voidCMainFrame:
:
task_run()
{
if(run==NULL&&ready->next!
=NULL)
run=ready->next;
ready->next=run->next;
run->next=NULL;
run->status=1;
if(run==ready_end)ready_end=ready;
}
voidCMainFrame:
:
pcb_recycle()//PCB回收机制.
{
free_end->next=run;
free_end=run;
free_end->status=0;
free_end->end_time=task_timer;
run=NULL;
}
<3>短作业进程优先调度算法(SPF)。
根据短作业进程优先调度算法定义,调用task_run_spf()函数以“need_time”为比较找出需要时间最短的PCB,进行显示
后调用pcb_recycle()释放run空间;而后继续调用task_run_spf()函数直到
PCB队列结束。
voidCMainFrame:
:
spf()
{
if(run!
=NULL||ready->next!
=NULL||blocked->next!
=NULL){
task_run_spf();
if(run!
=NULL){
run->need_time--;
if(run->need_time==0){
pcb_recycle();task_run_spf();if(run!
=NULL)run->wait_time++;
}
}
}
elseapp_status=false;
}
voidCMainFrame:
:
task_run_spf()
{
if(run==NULL&&ready->next!
=NULL)
{
PCB*p,*q,*r;//r指向p前一个PCB,q为搜索指针
r=ready;
p=q=ready->next;
while(q!
=NULL){
if(p->need_time>q->need_time)p=q;while(r->next!
=p)r=r->next;
q=q->next;
}
r->next=p->next;
run=p;
run->next=NULL;
run->status=1;
if(run==ready_end)ready_end=ready;
}
}
<3>时间片轮转调度算法。
根据时间片轮转调度算法定义,设定时间片为
TIME_CHIP=3,调用task_run()函数,从PCB队列中取出一个PCB,判断此PCB能否在一个时间片内执行完毕,如果不可以,在执行完毕后调用task_exchange_timeRoll(函数切换进程,并使用task_block()函数将此进程置于
PCB队列最后;如果可以,释放此PCB所占空间后,调用task_run()函数继续调入后面PCB。
反复直到PCB进行完毕。
voidCMainFrame:
:
timeRoll()
{
if(run!
=NULL||ready->next!
=NULL||blocked->next!
=NULL){
task_run();
if(run!
=NULL){
if((time_chip--)==0){//进程切换.
task_exchange_timeRoll();time_chip=TIME_CHIP;
}
elserun->need_time--;
if(run->need_time==0){
time_chip=TIME_CHIP;pcb_recycle();
task_run();
if(run!
=NULL)run->wait_time++;
}
}
if(rand()%5==0){
task_block();
task_run();
}
if(rand()%5==4)task_wake();
}
elseapp_status=false;
}
voidCMainFrame:
:
task_exchange_timeRoll()
{
if(ready->next!
=NULL)
ready_end->next=run;ready_end=run;
ready_end->status=0;
run=NULL;
task_run();
}
}
voidCMainFrame:
:
task_block()
{
if(run!
=NULL){blocked_end->next=run;blocked_end=run;blocked_end->status=2;run=NULL;
}
}
voidCMainFrame:
:
task_wake()
{
if(blocked->next!
=NULL){if(blocked->next==blocked_end)blocked_end=blocked;ready_end->next=blocked->next;
ready_end=ready_end->next;blocked->next=ready_end->next;ready_end->next=NULL;
ready_end->status=0;
}
}
<4>优先权调度算法。
根据优先权调度算法定义,此算法将最初处于最高优先权的PCB完成之后再进行第二优先权PCB,即使用非抢占式优先权算法。
它使用task_run_priority()函数找出优先权最高的PCB进程,然后进行,完成后释放空间;并继续调用task_run_priority()函数,直到PCB队列结束。
voidCMainFrame:
:
priority()
{
if(run!
=NULL||ready->next!
=NULL||blocked->next!
=NULL){
task_run_priority();
if(run!
=NULL){
run->need_time--;
if(run->need_time==0){
pcb_recycle();
task_run_priority();if(run!
=NULL)run->wait_time++;
}
}
}
elseapp_status=false;
}
voidCMainFrame:
:
task_run_priority()
{
if(run==NULL&&ready->next!
=NUL
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 课程设计 报告 进程 作业 调度
![提示](https://static.bdocx.com/images/bang_tan.gif)