优先级法多级反馈轮转法进程调度模拟设计.docx
《优先级法多级反馈轮转法进程调度模拟设计.docx》由会员分享,可在线阅读,更多相关《优先级法多级反馈轮转法进程调度模拟设计.docx(37页珍藏版)》请在冰豆网上搜索。
优先级法多级反馈轮转法进程调度模拟设计
学号:
课程设计
题目
进程调度模拟设计——优先级法、多级反馈轮转法
学院
计算机学院
专业
班级
姓名
指导教师
吴利军
2013
年
1
月
15
日
课程设计任务书
学生姓名:
指导教师:
吴利军工作单位:
计算机科学与技术学院
题目:
进程调度模拟设计——优先级法、多级反馈轮转法
初始条件:
1.预备内容:
阅读操作系统的处理机管理章节内容,对进程调度的功能以及进程调度算法有深入的理解。
2.实践准备:
掌握一种计算机高级语言的使用。
要求完成的主要任务:
(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
1.模拟进程调度,能够处理以下的情形:
⑴能够选择不同的调度算法(要求中给出的调度算法);
⑵能够输入进程的基本信息,如进程名、优先级、到达时间和运行时间等;
⑶根据选择的调度算法显示进程调度队列;
⑷根据选择的调度算法计算平均周转时间和平均带权周转时间。
2.设计报告内容应说明:
⑴需求分析;
⑵功能设计(数据结构及模块说明);
⑶开发平台及源程序的主要部分;
⑷测试用例,运行结果与运行情况分析;
⑸自我评价与总结:
)你认为你完成的设计哪些地方做得比较好或比较出色;
)什么地方做得不太好,以后如何改正;
)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);
)完成本题是否有其他方法(如果有,简要说明该方法);
时间安排:
设计安排一周:
周1、周2:
完成程序分析及设计。
周2、周3:
完成程序调试及测试。
周4、周5:
验收、撰写课程设计报告。
(注意事项:
严禁抄袭,一旦发现,一律按0分记)
指导教师签名:
年月日
系主任(或责任教师)签名:
年月日
进程调度模拟设计
——优先级法、多级轮转反馈法
1设计目的与功能
1.1设计目的
了解进程调度中的相关知识,能够使用其中的方法来进行进程调度模拟设计。
本次课程设计的重点是多级轮转反馈法和优先级法的使用,要求熟练掌握并运用他们,并能够运用一种高级语言来完成这个程序。
1.2设计功能
模拟进程调度,能够处理以下的情形:
⑴能够选择不同的调度算法(要求中给出的调度算法);
⑵能够输入进程的基本信息,如进程名、优先级、到达时间和运行时间等;
⑶根据选择的调度算法显示进程调度队列;
⑷根据选择的调度算法计算平均周转时间和平均带权周转时间。
2.需求分析,数据结构或模块说明(功能与框图)
2.1需求分析
无论是在批处理系统、分时系统还是实时系统,用户进程数一般都多于处理机数,这将导致用户进程互相争夺处理机。
另外,系统进程也同样需要使用处理机。
这就要求进程调度程序按照一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。
进程调度的主要任务是按照某种策略和方法选取一个处于就绪状态的进程占用处理机。
这次课程设计所要求使用的方法是时间片轮转和优先级法,并且能够选择不同的算法。
而时间片轮转法的基本思路是让每个进程在就绪队列中的等待时间与享受服务的时间成比例。
时间片轮转法的基本概念是将CPU的处理时间分成固定大小的时间片。
如果一个进程选中之后用完了系统规定的时间片,但未完成要求的任务,则它自行释放自己所占有的CPU而排到就绪队列的末尾,等待下一次调度。
同时,进程调度程序又去调度当前就绪队列中的第一个进程或作业。
优先级法是系统或用户按某种原则为作业或进程指定一个优先级来表示该作业或进程所享有的调度优先权。
优先级高的作业或进程优先调度。
根据所需求,这个进程调度的实现过程如下图所示:
2.2数据结构和模块说明
主要数据结构:
structPCB{
charname[NAME_LEN];
intpriority;//优先级
intarrive_time;//到达时间,即创建时间
intrun_time;//需要的时间片数
intfinish_time;//完成时间
intsleep_time;//用于模拟进程的阻塞耗时
intswitch_time;//切换队列的时间(SRR专用)
intused_run_time;//已经用过的时间片数
shortuse_slices;//每次占用CPU将消耗的时间片数不同队列中的进程的值不一样(RRMF专用)
structPCB*next;
};
程序中主要函数
charget_command();//显示主菜单并接受用户令
voidadd_process();//添加一个PCB结构进入预先准备队列
voidstart_scheduling();//演示进程调度队列,SRR版
voidstart_scheduling_rrmf();//RRMF版
voidcalculate_time_costs();//计算并显示平均周转时间,平均带权周转时间
voidswitch_algorithm();//切换调度算法(线性优先级法,多级反馈轮转法)
voidview_list(structPCB*list);//查看队列中内容
voidhelp_menu();//显示帮助菜单
voidrestart();//释放资源,重新开始
voidman_auto();//手动自动切换
voidappend(structPCB**head,structPCB**node);//添加于所指队列的队尾
voidshow_process(structPCB*node);//显示一个PCB的内容
voidtime_slice();//一个时间片
voidproc_run();//进程执行
voidproc_run_rrmf();//RRMF版
voidproc_switch();//进程切换
voidproc_switch_rrmf();//RRMF版
voidtry_wakeup_procs();//遍历等待队列,减少sleep_time,唤醒sleep_time降至进程
3.源程序的主要部分
本次程序主要由三个部分组成:
main函数部分,该部分主要包含main函数;LRU算法部分,该部分主要包含LRU函数、setm(intm,intn)函数和mini(int*b)函数;OPT算法部分,该部分主要包含OPT函数和getOpt(intinPage)函数。
3.1main函数部分
3.1.1main函数代码:
intmain(intargc,char*argv[])
{
charcommand;
srand((unsigned)time(NULL));
restart();
while((command=get_command())!
='0');
}
3.2进程调度方法部分
3.2.1.多级轮转反馈函数代码:
//进程执行(RRMF算法)
voidproc_run_rrmf()
{
shortslices_out=0;
try_wakeup_procs();
printf(">");
if(running==NULL){
printf(没?
有®D进?
程¨¬到Ì?
达ä?
!
\n");
return;
}
printf("进程正在运行:
",running->name);
running->used_run_time++;
running->next=NULL;
show_process(running);
printf("\n");
if(running->used_run_time==running->run_time)
{
running->finish_time=sys_clock;
running->use_slices=(QUEUE_NUM+1)-running->priority;
append(&finished_list,&running);
slices_out=1;
}
elseif((rand()%100+1)<30){
running->sleep_time=(rand()%5+1);
running->use_slices=(QUEUE_NUM+1)-running->priority;
append(&waiting_list,&running);
slices_out=1;
}
else{
running->use_slices--;
if(0==running->use_slices){
slices_out=1;
if(running->priority>PRIORITY4)
running->priority--;
running->use_slices=(QUEUE_NUM+1)-running->priority;
append(&ready_list[QUEUE_NUM-running->priority],&running);
}
}
if(slices_out)
running=NULL;
}
3.2.2.优先级法函数代码
voidproc_run()
{
try_wakeup_procs();
printf(">");
if(running==NULL){printf("没有进程抵达\n");
return;
}
printf("进程正在运行:
",running->name);
running->used_run_time++;
running->next=NULL;
show_process(running);
printf("\n");
if(running->used_run_time==running->run_time)
{
running->finish_time=sys_clock;
append(&finished_list,&running);
}
elseif((rand()%100+1)<30){
running->sleep_time=(rand()%5+1);
append(&waiting_list,&running);
}
else{
append(&serving_ready_list,&running);
}
running=NULL;
}
4.测试用例,运行结果与运行情况分析
4.1测试用例
运行界面
4.2运行结果
用多级轮转反馈法进行进程调度的结果如下图所示:
用优先级法进行进程调度所得到的结果如下图所示:
5.自我评价与总结
5.1本次课程设计做得比较好地方
本次课程设计条理清楚,能够运用两种不同的方法来进行进程调度。
在进程调度函数的实现时运用的结构体来实现各个的功能。
5.2什么地方做得不太好,以后如何改正
实验中一些不太好的部分就是本次实验虽然完成了老师所要求的任务,但是程序设计的界面还不是很优秀,用户体验不是很好。
以后需要在这方面改进,一个好的程序不仅要有高效率,易读性,我认为还需要较好的用户体验,以后我要在这方面多加改进。
5.3从本设计得到的收获
通过这次课程设计,我对操作系统有了更进一层的理解,同时对以前学的c程序设计语言也有了更深的理解。
在本次实验中我遇到了很多困难,本次实验中的程序编写花了很久。
在这次课程设计中,我自己先熟悉各种知识,然后查找相关资料来实现一些所需要的功能,尤其是在那两个方法时所要运用到的一些知识。
我觉得在以后的学习过程中还应该多做这样的设计,它可以让我们把所学的理论用于实践,一方面可以检验并巩固我们所学的内容,另一方面可以让我们在实践中感到所学知识的实用性,从而提高我们的学习兴趣。
6.参考文献
[1]张绕学,《计算机操作系统教程》,清华大学出版社 ,2005年6月
[2]周湘贞,《操作系统原理与实践教程》清华大学出版社,2006年10月
[3]严蔚敏,《数据结构(C语言版)》清华大学出版社,2004年11月
[4]闵联营,《c++程序设计教程》武汉理工大学出版社,2005年7月
附:
源代码
Common.h
#ifndef__COMMON_H__
#define__COMMON_H__
#defineNAME_LEN20
#defineINC_FACTOR2
//模拟时间片的延时
#defineDELAY_COUNTER10000
//RRMF所需常量
#defineQUEUE_NUM4//就绪队列的条数
#definePRIORITY14
#definePRIORITY23
#definePRIORITY32
#definePRIORITY41
#defineUSE_SLICES11
#defineUSE_SLICES22
#defineUSE_SLICES33
#defineUSE_SLICES44
/********************全局数据结构和变量***********************/
//进程控制块PCB结构
structPCB{
charname[NAME_LEN];
intpriority;//优先级
intarrive_time;//到达时间,即创建时间
intrun_time;//需要的时间片数
intfinish_time;//完成时间
intsleep_time;//用于模拟进程的阻塞耗时
intswitch_time;//切换队列的时间(SRR专用)
intused_run_time;//已经用过的时间片数
shortuse_slices;//每次占用CPU将消耗的时间片数,不同队列中的进程的值不一样(RRMF专用)
structPCB*next;
};
intsys_clock=0;//模拟系统时钟
intadd_idx=0;//第几轮添加进程
intpre_list_size=0;
shortalgorithm=0;//调度算法标记,0-SRR1-RRMF默认为0
charalgo_name[5]="SSR";
shortmanual=0;//手动,自动标记,0-手动1-自动默认为0
charoper_name[10]="Manual";
intnewly_factor=INC_FACTOR;//新创建进程优先级增长速率
intserving_factor=INC_FACTOR/2;//享受服务进程优先级增长速率
structPCB*pre_list;//预先准备的队列,用于模拟进程的不同时刻到达调度队列
structPCB*running;//指向正在运行进程
structPCB*serving_ready_list;//享受服务进程队列
structPCB*newly_ready_list;//新创建进程队列
structPCB*waiting_list;//等待队列
structPCB*finished_list=NULL;//完成队列
//RRMF的多级队列
//ready_list[0]优先级PRIORITY1,占时间片USE_SLICES1
//ready_list[1]优先级PRIORITY2,占时间片USE_SLICES2
//ready_list[2]优先级PRIORITY3,占时间片USE_SLICES3
//ready_list[3]优先级PRIORITY4,占时间片USE_SLICES4
//...
structPCB*ready_list[QUEUE_NUM];
/**************************函数说明****************************/
charget_command();//显示主菜单,并接受用户命令
voidadd_process();//添加一个PCB结构进入pre_list(预先准备队列)
voidstart_scheduling();//演示进程调度队列,SRR版
voidstart_scheduling_rrmf();//RRMF版
voidcalculate_time_costs();//计算并显示平均周转时间,平均带权周转时间
voidswitch_algorithm();//切换调度算法(线性优先级法,多级反馈轮转法)
voidview_list(structPCB*list);//查看队列中内容
voidhelp_menu();//显示帮助菜单
voidrestart();//释放资源,重新开始
voidman_auto();//手动/自动切换
voidappend(structPCB**head,structPCB**node);//添加node于head所指队列的队尾
voidshow_process(structPCB*node);//显示一个PCB的内容
voidtime_slice();//一个时间片
voidproc_run();//进程执行
voidproc_run_rrmf();//RRMF版
voidproc_switch();//进程切换
voidproc_switch_rrmf();//RRMF版
voidtry_wakeup_procs();//遍历等待队列,减少sleep_time,唤醒sleep_time降至0的进程
#endif//__COMMON_H__
Main.c
#include
#include
#include
#include
#include
#include"common.h"
intmain(intargc,char*argv[])
{
charcommand;
srand((unsigned)time(NULL));
restart();
while((command=get_command())!
='0');
}
//接收用户选择并转入相应的操作
charget_command()
{
charc;
printf("\n[%d个进程正在进行中,%s,%s,如果遇到问题,请按'6'查询]\n请选择将要进行的操作:
\n",pre_list_size,algo_name,oper_name);
c=_getch();
switch(c)
{
case'1':
add_process();break;
case'2':
switch_algorithm();break;
case'3':
if(algorithm==0)
start_scheduling();
else
start_scheduling_rrmf();
break;
case'4':
calculate_time_costs();break;
case'5':
view_list(pre_list);break;
case'6':
help_menu();break;
case'7':
restart();break;
case'8':
man_auto();break;
}
returnc;
}
//手动/自动切换
voidman_auto()
{
if(manual==0){
printf("切换为'自动模式'\n");
strcpy(oper_name,"Automatic");
manual=1;
}
else{
printf("切换为'手动模式'\n");
strcpy(oper_name,"Manual");
manual=0;
}
}
//显示帮助菜单
voidhelp_menu()
{
printf(
"===ProcessSchedulerSimulator===\n"
"1.添加进程\n"
"2.改变调度算法(目前算法为:
%s)\n"
"3.开始调度\n"
"4.计算平均周转时间、平均带权周转时间\n"
"5.查看就绪进程列表\n"
"6.帮助\n"
"7.重启\n"
"8.手动、自动切换(目前模式为:
%s)\n"
"0.退出\n",algo_name,oper_name
);
}
//添加node于head所指队列的队尾
voidappend(structPCB**head,structPCB**node)
{
structPCB*p;
//(*node)->next=NULL;
if(*head==NULL){
*head=*node;
return;
}
else{
p=*head;
while(p->next!
=NULL)p=p->next;
p->next=*node;
}
}
//添加进程
voidadd_process()
{
intcounterpart,i;
structPCB*tmp;
structPCB*p=malloc(sizeof(structPCB));
printf("请输入进程名称:
");
scanf("%s",p->name);
if(algorithm==0)//SRR线性优先级调度
p->priority=0;//优先级为0,表明使用SRR
else//RRMF多级反馈轮转法
p->priority=PRIORITY1;
p->use_slices=USE_SLICES1;//RRMF专用,表示占用的时间片
p->arrive_time=2*add_idx+rand()%1;
p->used_run_time=0;
p->sleep_time=-1;
p->finish_time=-1;
p->ne