实验三 进程调度模拟程序2.0
一、实验目的
用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、实验要求
设计一个有 N个进程并发执行的进程调度模拟程序。
1.模拟进程数据的生成
允许用户指定作业的个数(2-24),默认值为5。
允许用户选择输入每个进程的到达时间,所需运行时间,进程的运行时间以时间片为单位。
2. 模拟调度程序的功能
2.1 按照模拟数据的到达时间和所需运行时间,能分别执行以下调度算法。
FCFS
SJ
HRRN
RR
2.2 显示每种算法下各进程的调度执行顺序。
2.3计算各进程的开始执行时间,各作业的完成时间,周转时间和带权周转时间(周转系数)。
2.4模拟数据结果分析:对同一组模拟数据,比较各算法的平均周转时间,周转系数。
三、实验说明
1) 先来先服务(FCFS)调度算法,即按作业到达的先后次序进行调度。总是首先调度在系统中等待时间最长的作业。
2) 短作业优先 (SJF) 调度算法,优先调度要求运行时间最短的作业。
3) 响应比高者优先(HRRN)调度算法,为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度。RP (响应比)= 作业周转时间 / 作业运行时间=1+作业等待时间/作业运行时间。
4) 时间片轮转(RR)调度算法:调度程序每次把CPU分配给就绪队列首进程使用一个时间片,就绪队列中的每个进程轮流地运行一个时间片。当这个时间片结束时,强迫一个进程让出处理器,让它排列到就绪队列的尾部,等候下一轮调度。
四、实验环境
可以选用Turbo C作为开发环境。也可以选用Windows下的VB,CB等可视化环境,利用各种控件较为方便。自主选择实验环境。
五.代码
#include<stdio.h>
#include <stdlib.h>
#include <conio.h>
#define getpch(type) (type*)malloc(sizeof(type)) //为进程创建一个空间
struct worktime{
float Tb; //作业运行时刻
float Tc; //作业完成时刻
float Ti; //周转时间
float Wi; //带权周转时间
};
struct jcb {
char name[10]; //作业名
float arrivetime; //作业到达时间
float runtime; //作业所需的运行时间
char resource; //所需资源
float Rp; //后备作业响应比
char state; //作业状态
int worked_time; //已运行时间
struct worktime wt;
int need_time; //需要运行的时间
int flag; //进程结束标志
struct jcb* link; //链指针
}*ready=NULL,*p;
typedef struct jcb JCB;//重命名结构体
float T=0;
int N;
JCB *front,*rear;
void sort()
{
JCB *first, *second;
int insert=0; //插入数
if((ready==NULL)||((p->arrivetime)<(ready->arrivetime)))
{
p->link=ready;
ready=p;
T=p->arrivetime;
p->Rp=1;
}
else
{
first=ready;
second=first->link;
while(second!=NULL)
{
if((p->arrivetime)<(second->arrivetime))
{
p->link=second;
first->link=p;
second=NULL;
insert=1;
}
else
{
first=first->link;
second=second->link;
}
}
if (insert==0) first->link=p;
}
}
void SJFget()
{
JCB *front,*mintime,*rear;
int ipmove=0;
mintime=ready;
rear=mintime->link;
while(rear!=NULL)
{
if ((rear!=NULL)&&(T>=rear->arrivetime)&&(mintime->runtime)>(rear->runtime))
{
front=mintime;
mintime=rear;
rear=rear->link;
ipmove=1;
}
else
rear=rear->link;
}
if (ipmove==1)
{
front->link=mintime->link;
mintime->link=ready;
}
ready=mintime;
}
void HRNget()
{
JCB *front,*mintime,*rear;
int ipmove=0;
mintime=ready;
rear=mintime->link;
while(rear!=NULL)
if ((rear!=NULL)&&(T>=rear->arrivetime)&&(mintime->Rp)<(rear->Rp))
{
front=mintime;
mintime=rear;
rear=rear->link;
ipmove=1;
}
else
rear=rear->link;
if (ipmove==1){
front->link=mintime->link;
mintime->link=ready;
}
ready=mintime;
}
void creatJCB() //为每个作业创建一个JCB并初始化形成一个循环链队列
{
JCB *p,*l;
int i=0;
l = (JCB *)malloc(sizeof(JCB));
printf("\n 请输入作业的个数:");
scanf("%d",&N);
printf("\n 作业号No.%d:\n",i);
printf("\n请输入作业的名字:");
scanf("%s",l->name);
printf("\n请输入作业需要运行的时间:");
scanf("%d",&l->need_time);
l->state = 'r'; //作业初始状态为就绪(即准备状态)
l->worked_time = 0;
l->link=NULL;
l->flag=0;
front=l;
for(i =1;i<N;i++)
{
p = (JCB *)malloc(sizeof(JCB));
printf("\n 作业号No.%d:\n",i);
printf("\n请输入作业的名字:");
scanf("%s",p->name);
printf("\n请输入作业的时间:");
scanf("%d",&p->need_time);
p->state='r';
p->worked_time=0;
p->flag=0;
l->link=p;
l=l->link;
}
rear=l;rear->link=front;
}
void output()//进程输出函数
{
int j;
printf("name runtime needtime state\n");
for(j=1;j<=N;j++)
{ printf(" %-4s\t%-4d\t%-4d\t%-c\n",front->name,front->worked_time,front->need_time,front->state);
front=front->link;
}
printf("\n");
}
int judge(JCB *p) //判断所有进程运行结束
{
int flag=1,i;
163 for(i=0;i<N;i++)
{
if(p->state!='e')
{
flag = 0;
break;}
p=p->link;
}
return flag;
}
//作业输入
void input()
{
int i,num;
printf("\n 请输入作业的个数:");
scanf("%d",&num);
for(i=0;i<num;i++)
{
printf(" 作业号No.%d:\n",i);
p=getpch(JCB);
printf(" 输入作业名:");
scanf("%s",p->name);
printf(" 输入作业到达时刻:");
scanf("%f",&p->arrivetime);
printf(" 输入作业运行时间:");
scanf("%f",&p->runtime);
printf("\n");
p->state='w';
p->link=NULL;
sort();
}
}
int space()
{
int l=0; JCB* jr=ready;
while(jr!=NULL)
{
l++;
jr=jr->link;
}
return(l);
}
void disp(JCB* jr,int select)
{
if (select==3) printf("\n 作业 到达时间 服务时间 响应比 运行时刻 完成时刻 周转时间 带权周转时间 \n");
else printf("\n 作业 到达时间 服务时间 运行时刻 完成时刻 周转时间 带权周转时间 \n");
printf(" %s\t",jr->name);
printf("%.2f\t ",jr->arrivetime);
printf("%.2f\t",jr->runtime);
if (select==3&&p==jr) printf(" |%.2f ",jr->Rp);
if (p==jr){
printf(" %.2f\t",jr->wt.Tb);
printf(" %.2f ",jr->wt.Tc);
printf(" %.2f\t",jr->wt.Ti);
printf(" %.2f",jr->wt.Wi);
}
//printf("\n");
}
int destroy()
{
free(p);
return(1);
}
void check(int select)
{
JCB* jr;
printf(" 是 :%s",p->name);//当前执行的作业是
disp(p,select);
jr=ready;
destroy();
}
void running(JCB* jr)
{
if (T>=jr->arrivetime) jr->wt.Tb=T;
else jr->wt.Tb=jr->arrivetime;
jr->wt.Tc=jr->wt.Tb+jr->runtime;
jr->wt.Ti=jr->wt.Tc-jr->arrivetime;
jr->wt.Wi=jr->wt.Ti/jr->runtime;
T=jr->wt.Tc;
}
int main()
{
int select=0,len,h=0;
float sumTi=0,sumWi=0;
printf("请选择作业调度算法的方式:\n");
printf("\t1.FCFS 2.SJF 3.HRN \n");
printf("请输入作业调度算法序号(1-3):");
scanf("%d",&select);
input(); //调用输入函数
len=space();
while((len!=0)&&(ready!=NULL))
{
h++;
printf(" 第%d个执行作业 ",h);
p=ready;
ready=p->link;
p->link=NULL;
p->state='R';
running(p);
sumTi+=p->wt.Ti;
sumWi+=p->wt.Wi;
check(select); //与所选择的算法比较,调用void check(int select)
if (select==2&&h<len-1) SJFget();
if (select==3&&h<len-1) HRNget();
getchar();
getchar();
}
printf(" 作业已经完成.\n");
printf("\t 此组作业的平均周转时间:%.2f\n",sumTi/h);
printf("\t 此组作业的带权平均周转时间:%.2f\n",sumWi/h);
getchar();
}
实验结果截图:
总结与体会
通过本次实验,感觉自己对之前数据结构的算法和语法掌握得不是很好,虽然会定义结构体比较熟练,但是对于在程序中调用结构体就不太理解,导致多次出错,并通过查阅相关资料,然后不断修改,由于之前的数据结构学得不扎实,所以写代码遇到很多困难,往后要多回顾旧知识,特别是语法结构和新接触的几种作业调度的算法思想。
posted on 2016-06-15 16:44 huanglinsheng 阅读(274) 评论(0) 编辑 收藏 举报