进程调度模拟设计——先来先服务、优先级法教材
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学号:
课程设计
进程调度模拟设计——先来题目
先服务、优先级法
学院计算机科学与技术
专业
班级
姓名
指导教师吴利军
2013 年 1 月16 日
课程设计任务书
学生姓名:专业班级:
指导教师:吴利军工作单位:计算机科学与技术学院题目: 进程调度模拟设计——先来先服务、优先级法初始条件:
1.预备内容:阅读操作系统的处理机管理章节内容,对进程调度的功能以及进程调度算法有深入的理解。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写
等具体要求)
1.模拟进程调度,能够处理以下的情形:
⑴能够选择不同的调度算法(要求中给出的调度算法);
⑵能够输入进程的基本信息,如进程名、优先级、到达时间和运行时间等;
⑶根据选择的调度算法显示进程调度队列;
⑷根据选择的调度算法计算平均周转时间和平均带权周转时间。
2.设计报告内容应说明:
⑴需求分析;
⑵功能设计(数据结构及模块说明);
⑶开发平台及源程序的主要部分;
⑷测试用例,运行结果与运行情况分析;
⑸自我评价与总结:
i)你认为你完成的设计哪些地方做得比较好或比较出色;
ii)什么地方做得不太好,以后如何改正;
iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);
iv)完成本题是否有其他方法(如果有,简要说明该方法);
时间安排:
设计安排一周:周1、周2:完成程序分析及设计。
周2、周3:完成程序调试及测试。
周4、周5:验收、撰写课程设计报告。
(注意事项:严禁抄袭,一旦发现,一律按0分记)
指导教师签名:年月日
系主任(或责任教师)签名:年月日
进程调度模拟设计——先来先服务、优先级法1、背景:
当计算机系统是多道程序设计系统时,通常会有多个进程或线程同时竞争CPU。
只要有两个或更多的进程处于就绪状态,这种情形就会发生。
如果只有一个CPU可用,那么就必须选择下一个要运行的进程。
在操作系统中,完成选择工作的这一部分称为调度程序,该程序使用的算法成为调度算法。
进程调度的核心问题是采用什么样的算法把处理机分配给进程,好的算法将提高资源利用率,减少处理机的空闲时间,避免有些作业长期得不到相应的情况发生等,从而设计出受欢迎的操作系统。
较常见的几种进程调度算法有:先来先服务调度算法;短作业优先调度算法;时间片轮转调度算法;优先级调度算法;高响应比优先算法和多级反馈队列调度算法等。
2、需求分析:
2.1设计目的
无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它们互相争夺处理机。
另外,系统进程也同样需要使用处理机。
这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。
本次课程设计的主要任务是用高级语言模拟进程调度的算法,包括先来先服务和优先级法。
通过输入进程的信息,模拟某种调度算法,得到进程调度的顺序,从而进一步分析进程的调度过程,并通过分析程序的运行,探讨各种调度算法的优劣。
2.2 设计内容及要求
本系统运用高级语言来实现对进程调度的模拟。
系统需要完成的功能有:
①进程信息的输入,包括进程的个数、进程名、进程优先级、进程开始时
间、进程执行时间等。
②进程调度算法的选择,即为用户提供可选的进程调度算法,用户可以根
据需要选择调度算法。
③根据进程调度的算法和输入的进程信息得到进程的调度顺序,并输出。
④计算并输出各个进程的平均周转时间和平均带权周转时间。
2.3算法与设计的思想
2.3.1算法思想:
·一个进程的生命期可以划分为一组状态,这些状态刻画了整个进程。
系统根据PCB结构中的状态值控制过程。
在进程的生命期内,一个进程至少具有5种基本状态,它们是:初始态、执行状态、等待状态、就绪状态和终止状态。
通过系统设计,实现进程相关数据结构的创建和查看功能;实现多种进程调度算法:先来先服务算法、优先级调度算法、时间片轮转法等;实现对执行进程的阻塞,对等待进程的唤醒等功能。
进程的转换过程如下:
·进程的先来先服务调度算法:
首先定义进程结构体,用于记录进程的基本信息,包括进程名,优先级,进程到达时间,进程运行时间,然后将用户输入的进程信息保存到定义的结构数组中,并按进程到达的先后时间对数组进行排序,并记录它们的周转时间、带权周转时间、平均周转时间及平均带权周转时间。
·进程的优先级调度算法:
同样先定义进程结构替,记录进程信息,将用户输入的进程信息保存在结构体数组中。
遍历数组,找出最先到达的进程,若有多个,则取优先级最高的一个,与数组中的第一个位置的进程互换位置,记录此进程执行完的时间,然后从第二个位置开始遍历数组,找到在第一个进程执行结束前到达的进程,若没有,则找到余下进程中到达时间最早的进程,找到优先级最高的一个,若并与数组的第二个位置的进程互换位置。
按同样的方法为余下的进程排序。
同样记录它们的周转时间,带权周转时间,并算出平均周转时间和平均带权周转时间。
2.3.2设计思想:
a)每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信
息:进程名、优先级数、到达时间、需要运行时间等等。
b)进程的信息,包括到达时间,优先数及需要的运行时间等都是事先人为
地指定。
c)每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)
三种状态之一。
3、功能设计(数据结构及模块说明);
3.1 系统流程如下:
3.2数据结构及模块说明:
(1)输入模块
能够满足输入进程基本信息的功能,尽可能提供友好的交互界面。
给用户很好的提示,使用户能够方便的操作。
(2)算法模块
先来先服务算法:
可以根据进程到达的先后顺序来确定进程的运行顺序,并算出进程的周转时间,平均周转时间等。
优先级法:
根据进程的优先级和进程到达的时间来确定进程的调度顺序,并算出周转时间,带权周转时间等。
(3)输出模块
根据算法得到的进程调度顺序以及算出的其他参数,将其输出。
4、开发平台及源程序的主要部分;
4.1软硬件环境
●硬件设备: PC机
●软件设备:WINDOWSXP、Microsoft Visual C++ 6.0
4.2 源代码主要部分:
(1)信息输入函数:
void getInput(char *pname,int *priority,char *begintime,float *runtime) {
printf("请输入进程名:");
scanf("%s",pname);
printf("请输入优先级");
scanf("%d",priority);
printf("请输入到达时间:");
scanf("%s",begintime);
printf("请输入¨运行时间(min):");
scanf("%f",runtime);
}
(2)先来先服务的算法:
void fcfs(struct process *pro,int n)
{
int i,j;
struct process p;
for(i = 0;i < n;i ++)
{
for(j = 0;j < n - i -1;j ++)
{
if(!timecompare(pro[j],pro[j+1]))
{
p = pro[j + 1];
pro[j + 1] = pro[j];
pro[j] = p;
}
}
}
}
(3)优先级法的算法:
void prior(struct process *pro,int n)
{
int i,j,pt,t,bt,m;
bt = 0;
int a[MAXPROCESS];
struct process p;
float curtime = 1500; //当Ì¡À前¡ã时º¡À间?
for(i = 0;i < n;i ++)
{
if(curtime > pro[i].btime)
{
curtime = pro[i].btime;
}
}
for(i = 0;i < n;i ++)
{
t = 0;
pt = 0;
for(j = i;j < n;j++)
{
if(pro[j].btime <= curtime)
{
a[t++] = j;
}
}
if(t == 0)
{
curtime = 1500;
for(j = i;j < n;j ++)
{
if(curtime > pro[j].btime)
{
curtime = pro[j].btime;
}
}
for(j = i;j < n;j++)
{
if(pro[j].btime <= curtime)
{
a[t++] = j;
}
}
}
for(j = 0;j < t;j++)
{
bt = a[j];
if(pro[bt].priority > pt)
{
pt = pro[bt].priority;
m = bt;
}
}
if(m != i)
{
p = pro[m];
pro[m] = pro[i];
pro[i] = p;
}
curtime = curtime + pro[i].runtime;
}
}
5、测试用例,运行结果与运行情况分析;
5.1测试用例:
①进程个数为4
②进程名唯一
③预计运行结果:
先来先服务:c a d b
优先级法:c a b d
5.2运行结果:
6、自我评价与总结:
通过这次的课程设计熟悉了优先级法以及先来先服务算法在处理进程调度的问题上的应用,熟悉了它们各自的特点以及各自的优缺点。
在实验结果中可以看到优先级法在处理特殊进程问题上有很大的意义,可以有效地缩短平均周转时间以及平均带权周转时间,而先来先服务实现简单,两种方法各有所长。
在程序调试的过程中遇到了很多的麻烦,有时编译运行没有问题但结果不对,通过设置断点单步调试却发现只是丢了一个赋值或者拷贝时忘了某些内容,这些小错误耽误了不少时间,所以在以后的编程过程中要养成随时给变量赋初值的习惯。
有些在算法编制的过程中遇到的问题确实有点棘手,但是随着这些问题的解决又使自己在这一方面的能力上有了比较大的提高。
但是同时我仍然看到了自己的不足,与别人比起来仍然有不小的差距。
自己用的时间比别人长,但是效果又不如别人的好。
所以自己还应该继续努力。
本科生课程设计成绩评定表
注:最终成绩以五级分制记。
优(90-100分)、良(80-89分)、中(70-79分)、
及格(60-69分)、60分以下为不及格
指导教师签名:
20 年月日
附录:
#include"stdafx.h"
#include"stdlib.h"
#include"string.h"
#define PNNUM 20
#define TIME 6 //时º¡À间?的Ì?长¡è度¨¨
#define MAXPROCESS 10
// 进?程¨¬结¨¢构1
struct process{
char name[PNNUM]; //进?程¨¬名?
int priority; //优®?先¨¨级?
char begintime[TIME]; //开a始º?时º¡À间?
int btime; //开a始º?时º¡À间?(ꡧ转Áa换?为a分¤?钟¨®)ê?
float runtime; //运?行D时º¡À间?
float routime; //周¨¹转Áa时º¡À间?
float qtime; //带ä?权¨¡§周¨¹转Áa时º¡À间?
}pro[MAXPROCESS];
// 输º?入¨?进?程¨¬参?数ºy
void getInput(char *pname,int *priority,char *begintime,float *runtime) {
printf("请?输º?入¨?进?程¨¬名?:êo");
scanf("%s",pname);
printf("请?输º?入¨?优®?先¨¨级?:êo");
scanf("%d",priority);
printf("请?输º?入¨?到Ì?达ä?时º¡À间?:êo");
scanf("%s",begintime);
printf("请?输º?入¨?运?行D时º¡À间?(min):êo");
scanf("%f",runtime);
}
//将?开a始º?时º¡À间?转Áa换?为a分¤?钟¨®
void ttoi(struct process *pro,int n)
{
int h,m;
char a[3],b[3];
int i;
for(i = 0;i < n; i ++)
{
int j;
for(j = 0;pro[i].begintime[j] != ':';j ++)
{
a[j] = pro[i].begintime[j];
}
b[0] = pro[i].begintime[j + 1];
b[1] = pro[i].begintime[j + 2];
h = atoi(a); //得Ì?到Ì?小?时º¡À
m = atoi(b); //得Ì?到Ì?分¤?钟¨®
pro[i].btime = h * 60 + m;
}
}
//比À¨¨较?两¢?个?进?程¨¬到Ì?达ä?时º¡À间?,若¨?同ª?时º¡À到Ì?或¨°pro1早?到Ì?,ê?则¨°返¤¦Ì回?1
int timecompare(struct process pro1,struct process pro2)
{
return pro1.btime > pro2.btime ? 0 : 1;
}
//根¨´据Y进?程¨¬到Ì?达ä?时º¡À间?排?队¨®
void fcfs(struct process *pro,int n)
{
int i,j;
struct process p;
for(i = 0;i < n;i ++)
{
for(j = 0;j < n - i -1;j ++)
{
if(!timecompare(pro[j],pro[j+1]))
{
p = pro[j + 1];
pro[j + 1] = pro[j];
pro[j] = p;
}
}
}
}
//计?算?周¨¹转Áa时º¡À间?和¨ª带ä?权¨¡§周¨¹转Áa时º¡À间?
void calculate(struct process *pro,int n)
{
int i;
pro[0].routime = pro[0].runtime;
pro[0].qtime = 1;
for(i = 1;i < n;i ++)
{
if(pro[i - 1].btime + pro[i - 1].routime >= pro[i].btime)
pro[i].routime =pro[i - 1].btime + pro[i - 1].routime + pro[i].runtime - pro[i].btime;
else
pro[i].routime = pro[i].runtime;
pro[i].qtime = pro[i].routime / pro[i].runtime;
}
}
//计?算?平?均¨´周¨¹转Áa时º¡À间?和¨ª平?均¨´带ä?权¨¡§周¨¹转Áa时º¡À间?
void calAver(struct process *pro,int n,float *avartime,float *avarqtime)
{
int i;
float t1,t2;
t1 = t2 = 0;
for(i = 0;i < n;i++)
{
t1 += pro[i].routime;
t2 += pro[i].qtime;
}
*avartime = t1 / n;
*avarqtime = t2 / n;
}
//非¤?抢¨¤占?式º?优®?先¨¨级?法¤¡§
void prior(struct process *pro,int n)
{
int i,j,pt,t,bt,m;
bt = 0;
int a[MAXPROCESS];
struct process p;
float curtime = 1500; //当Ì¡À前¡ã时º¡À间?
for(i = 0;i < n;i ++)
{
if(curtime > pro[i].btime)
{
curtime = pro[i].btime;
}
}
for(i = 0;i < n;i ++)
{
t = 0;
pt = 0;
for(j = i;j < n;j++)
{
if(pro[j].btime <= curtime)
{
a[t++] = j;
}
}
if(t == 0)
{
curtime = 1500;
for(j = i;j < n;j ++)
{
if(curtime > pro[j].btime)
{
curtime = pro[j].btime;
}
}
for(j = i;j < n;j++)
{
if(pro[j].btime <= curtime)
{
a[t++] = j;
}
}
}
for(j = 0;j < t;j++)
{
bt = a[j];
if(pro[bt].priority > pt)
{
pt = pro[bt].priority;
m = bt;
}
}
if(m != i)
{
p = pro[m];
pro[m] = pro[i];
pro[i] = p;
}
curtime = curtime + pro[i].runtime;
}
}
void print(struct process *pro,int n,float f1,float f2)
{
int i;
printf("进?程¨¬调Ì¡Â度¨¨顺3序¨°为a:êo\n");
printf("-----------------------------------------------------------\n");
printf("调Ì¡Â度¨¨顺3序¨°优®?先¨¨级? 到Ì?达ä?时º¡À间? 运?行D时º¡À间? 周¨¹转Áa时º¡À间? 带ä?权¨¡§周¨¹转Áa时º¡À间?\n");
for(i = 0;i < n;i ++)
{
printf("%8s %6d %8s %8.0f %8.0f %12.2f\n",pro[i].name,pro[i].priority,pro[i ].begintime,pro[i].runtime,pro[i].routime,pro[i].qtime);
}
printf("-----------------------------------------------------------\n");
printf("平?均¨´周¨¹转Áa时º¡À间?:êo\t%0.2f\t",f1);
printf("平?均¨´带ä?权¨¡§周¨¹转Áa时º¡À间?:êo\t%0.2f\t\n",f2);
printf("-----------------------------------------------------------\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("*********************\n");
printf("* 进?程¨¬调Ì¡Â度¨¨模¡ê拟a实º¦Ì验¨¦*\n");
printf("*********************\n");
int pronum =0;
int go = 1;
int input1 = 1;
int input2 = 1;
float f1,f2;
f1 = f2 = 0;
while(go == 1)
{
printf("请?输º?入¨?进?程¨¬数ºy(最Á?大䨮进?程¨¬数ºy位?为a10):êo");
scanf("%d",&pronum);
int n;
for(n = 0;n < pronum;n ++)
{
printf("进?程¨¬:%d:\n",n+1);
printf("---------------------------------\n");
getInput(pro[n].name,&pro[n].priority,pro[n].begintime,&pro[n].runtime);
printf("---------------------------------\n");
}
while(input2 == 1)
{
printf("****************************\n");
printf("*请?选?择?调Ì¡Â度¨¨算?法¤¡§:êo \n");
printf("*先¨¨来¤¡ä先¨¨服¤t务? --1 \n");
printf("*优®?先¨¨级?法¤¡§(ꡧ非¤?抢¨¤占?)ê? --2 \n");
printf("****************************\n");
printf("请?选?择?:êo");
scanf("%d",&input1);
ttoi(pro,pronum);
switch(input1)
{
case 1:
fcfs(pro,pronum);
break;
case 2:
prior(pro,pronum);
break;
}
calculate(pro,pronum);
calAver(pro,pronum,&f1,&f2);
print(pro,pronum,f1,f2);
printf("是º?否¤?重?新?选?择?算?法¤¡§:êo 是º?: 1 否¤?: 0\n");
scanf("%d",&input2);
}
printf("是º?否¤?继¨¬续?:êo 继¨¬续?: 1 退ª?出?: 0\n");
scanf("%d",&go);
}
return 0;
}。