1. 实验目的
用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
2. 实验要求
设计一个有 N个进程并发执行的进程调度模拟程序。
进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法。
(1). 每个进程有一个进程控制块(PCB)表示。进程控制块包含如下信息:进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态等等。
(2). 进程的优先级及需要的运行时间可以事先人为地指定,进程的运行时间以时间片为单位进行计算。
(3). 每个进程的状态可以是就绪 r(ready)、运行R(Running)、或完成F(Finished)三种状态之一。
(4). 就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。
(5). 如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待调度。
(6). 每进行一次调度程序都打印一次运行进程、就绪队列中各个进程的 PCB,以便进行检查。
(7). 重复以上过程,直到所要进程都完成为止。
3.实验环境
可以选用Turbo C作为开发环境。也可以选用Windows下的VB,CB等可视化环境,利用各种控件较为方便。自主选择实验环境。
4.作业调度算法:
1) 采用先来先服务(FCFS)调度算法,即按作业到达的先后次序进行调度。总是首先调度在系统中等待时间最长的作业。
2) 短作业优先 (SJF) 调度算法,优先调度要求运行时间最短的作业。
3) 响应比高者优先(HRRN)调度算法,为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度。RP (响应比)= 作业周转时间 / 作业运行时间=1+作业等待时间/作业运行时间
每个作业由一个作业控制块JCB表示,JCB可以包含以下信息:作业名、提交(到达)时间、所需的运行时间、所需的资源、作业状态、链指针等等。
作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种之一。每个作业的最初状态都是等待W。
5.源程序及其解释
#include<stdio.h>
#include<string.h>
typedef struct jcb{
char name[10];//作业名
int arrtime;//到达时间
int reqtime;//要求服务时间
int startime;//调度时间
int finitime;//结束时间
float TAtime,TAWtime;//周转时间,带权周转时间(周转时间/服务时间)
}JCB;
int systime=0;
int intarr=0,intfin=0,intjob=0;//到达作业个数,完成作业个数,未到达作业个数
JCB jobarr[24],jobfin[24],job[24];
void Input()//输入
{
int i;
int j;
int n=0;
printf("请输入作业个数:");
scanf("%d",&n);
for(i=0;i<n;i++,intjob++)
{
printf("\n第%d个作业:\n请输入作业名:",i+1);
scanf("%s",job[intjob].name);
do{
printf("请输入到达时间:");
scanf("%d",&job[intjob].arrtime);
if(job[i].arrtime<systime)
printf("到达时间小于当前系统时间!请重新输入:");
}while(job[i].arrtime<systime);
printf("请输入要求服务时间:");
scanf("%d",&job[intjob].reqtime);
job[i].startime=0;
job[i].finitime=0;
job[i].TAtime=0;
job[i].TAWtime=0;
}
for(i=0;i<intjob;i++)//若输入到达时间为现在的系统时间
{
if(job[i].arrtime==systime)
{
jobarr[intarr]=job[i];
for(j=i;j<=intjob;j++)
{
job[j]=job[j+1];
}
intarr++;
intjob--;
i--;
}
else if(job[i].arrtime<systime)
{
printf("到达时间小于当前系统时间!请重新输入");
}
}
}
void Output()//输出排序后队列
{
int i;
printf("\n\n\n未到达队列的是\n");
printf("\tname\tarrime\treqtime\tstartime fintime TAtime\tTAWtime\n");
for(i=0;i<intjob;i++){
printf("N%d\t%s\t%d\t%d\t%d\t %d\t %.2f\t%.2f\n",i+1,job[i].name,job[i].arrtime,job[i].reqtime,job[i].startime,job[i].finitime,job[i].TAtime,job[i].TAWtime);
}
printf("\n已到达队列的是\n");
printf("\tname\tarrime\treqtime\tstartime fintime TAtime\tTAWtime\n");
for(i=0;i<intarr;i++){
printf("N%d\t%s\t%d\t%d\t%d\t %d\t %.2f\t%.2f\n",i+1,jobarr[i].name,jobarr[i].arrtime,jobarr[i].reqtime,jobarr[i].startime,jobarr[i].finitime,jobarr[i].TAtime,jobarr[i].TAWtime);
}
printf("\n已完成队列的是\n");
printf("\tname\tarrime\treqtime\tstartime fintime TAtime\tTAWtime\n");
for(i=0;i<intfin;i++){
printf("N%d\t%s\t%d\t%d\t%d\t %d\t %.2f\t%.2f\n",i+1,jobfin[i].name,jobfin[i].arrtime,jobfin[i].reqtime,jobfin[i].startime,jobfin[i].finitime,jobfin[i].TAtime,jobfin[i].TAWtime);
}
printf("现在系统时间:%d",systime);
}
void Sort(JCB job[])//排序
{
int i,j;
JCB temp;
for(i=0;i<intjob-1;i++)
{
for(j=i+1;j<intjob;j++)
{
if(job[i].arrtime>job[j].arrtime)
{
temp=job[i];
job[i]=job[j];
job[j]=temp;
}
}
}
}
//先来先服务算法
void Fcfs(){
int i,j=0,k;
while(job[j].arrtime>systime)
{
systime++;
}
jobarr[intarr]=job[j];
for(k=j;k<=intjob;k++)
{
job[k]=job[k+1];
}
intarr++;
intjob--;
j--;
for(i=0;i<intarr;i++)
{
j=i;
jobarr[i].startime=systime;
jobarr[i].finitime=systime+jobarr[i].reqtime;
while(jobarr[i].finitime>systime||intjob!=0)
{
systime++;
if(job[j].arrtime==systime)//作业从未到达队列进入已到达队列
{
jobarr[intarr]=job[j];
for(k=j;k<=intjob;k++)
{
job[k]=job[k+1];
}
intarr++;
intjob--;
j--;
}
}
jobarr[i].TAtime=jobarr[i].finitime-jobarr[i].arrtime;
jobarr[i].TAWtime=jobarr[i].TAtime/jobarr[i].reqtime;
jobfin[intfin]=jobarr[i];
for(k=i;k<=intarr;k++)//队列中剩余元素前移
{
jobarr[k]=jobarr[k+1];
}
intarr--;
intfin++;
i--;
}
}
main()
{
char a;
char b[20];
int i,j,key=0;
Input();
//排序
Sort(job);
Sort(jobarr);
Output();
systime++;
while(1)
{
printf("\n\nInsert or Delete or Operating or Exit ?(I or D or O or E):");
getchar();
scanf("%c",&a);
if(a=='I'||a=='i')//插入
{
Input();
}
else if(a=='D'||a=='d')//删除(只删除在等待队列中的)
{
printf("请输入要删除的作业名:");
scanf("%s",b);
for(i=0;i<intjob;i++)
{
if(strcmp(b,job[i].name)==0)
{
key=1;
for(j=i;j<=intjob;j++)
{
job[j]=job[j+1];
}
intjob--;
}
}
if(key==0)
{
printf("查找不到该作业!");
}
}
else if(a=='O'||a=='o')
{
Fcfs();
printf("\n\n经过运行");
}
else if(a=='E'||a=='e')//退出
{
exit(0);
}
else
printf("输入错误!");
Sort(job);
Sort(jobarr);
Output();
systime++;
}
}
6.运行结果