一、实验目的
用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、实验内容和要求
要求:
设计一个有 N(N不小于5)个进程并发执行的进程调度模拟程序。
进程调度算法:“时间片轮转法”调度算法对N个进程进行调度。
内容:
完成两个算法(简单时间片轮转法、多级反馈队列调度算法)的设计、编码和调试工作,完成实验报告。
1) 每个进程有一个进程控制块(PCB)表示。进程控制块包含如下信息:进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态等等。
2) 每个进程的状态可以是就绪 r(ready)、运行R(Running)、或完成F(Finished)三种状态之一。
3) 就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。
4) 如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,应把它插入就绪队列等待下一次调度。
5) 每进行一次调度,程序都打印一次运行进程、就绪队列中各个进程的PCB,以便进行检查。
6) 重复以上过程,直到所要进程都完成为止。
三、实验方法、步骤及结果测试
1. 源程序名:proprity(rar或zip)中源程序名proprity.c
- 可执行程序名:proprity.exe
原理分析及流程图
主要设计思路:
该程序定义一个PCB的结构体,包含每个作业的名称、优先数、CPU占用时间、进程到完成需要的时间、进程的状态、链指针。先让用户输入作业的数目,然后输入每个作业的名称、作业完成所需要的时间。首先先判断就绪队列是否为空,若不为空,则将输入的进程插入到就绪队列中。否则,使其成为就绪队列的首个元素。其他进程以此类推。各进程占用CPU的时间片长度相同。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。最后显示出每一次模拟之后的结果执行算法的结果。
流程图:
主要程序段及其解释:
1.主要功能:实现进程插入到就绪队列的功能。
//优先数的算法插入算法
void insertToQueue(PRO *q)
{
PRO *p1,*s,*r;
int b;
s=q; //待插入的PRO指针
p1=ready; //就绪队列头指针
r=p1; //r做p1的前驱指针
b=1;
while((p1!=NULL)&&b) //根据优先数确定插入位置
if(p1->prio>=s->prio)//
{
r=p1;
p1=p1->next;
}
else
b=0;
if(r!=p1) //如果条件成立说明插入在r与p1之间
{
r->next=s;
s->next=p1;
}
else
{
s->next=p1; //否则插入在就绪队列的头
ready=s;
}
}
2.主要功能:实现进程的初始化以及进程状态的初始化
//优先数创建初始PRO信息
void createPro()
{
PRO *p;
int i,time;
char hao[10];
ready=NULL; //就绪队列头文件
finish=NULL; //完成队列头文件
run=NULL; //运行队列头文件
printf("输入进程号和运行时间: "); //输入进程标志和所需时间创建PRO
for(i=1;i<=NUM;i++)
{
p=(PRO *)malloc(sizeof(PRO));
scanf("%s",hao); //进程号
scanf("%d",&time); //运行时间
strcpy(p->name,hao);
p->cputime=0;
p->needtime=time;
p->state='w';
p->prio=30-time; // 优先级:用30减去相应的运行时间
if(ready!=NULL) //就绪队列不空,调用插入函数插入
insertToQueue(p);
else
{
p->next=ready; //创建就绪队列的第一个PRO
ready=p;
}
}
printf(" 多级反馈调度算法输出信息: ");
printf("*********************************************** ");
prt(); //输出进程PRO信息
run=ready; //将就绪队列的第一个进程投入运行
ready=ready->next;
run->state='R';
}
3.主要功能:调度算法的实现
//优先数调度算法
void priority()
{
while(run!=NULL) //当运行队列不空时,有进程正在运行
{
run->cputime=run->cputime+1;
run->needtime=run->needtime-1;
run->prio=run->prio-3; //每运行一次优先数降低3个单位
if(run->needtime==0) //如所需时间为0将其插入完成队列
{
run->next=finish;
finish=run;
run->state='F'; //置状态为完成态
run=NULL; //运行队列头指针为空
if(ready!=NULL) //如就绪队列不空
firstin(); //将就绪队列的第一个进程投入运行
}
else //没有运行完同时优先数不是最大,则将其变为就绪态插入到就绪队列
if((ready!=NULL)&&(run->prio<ready->prio))
{
run->state='W';
insertToQueue(run);
firstin(); //将就绪队列的第一个进程投入运行
}
prt(); //输出进程PRO信息
}
}
四、实验总结
通过这次实验,从最开始不明白如何实现进程调度,到现在大概了解了进程多级反馈调度算法。在编程的过程中,遇到了很多自己想不通的算法思路,还有一个重要的体会是要善于运用网络上的一些有用的资源,它可以成为你学习的一种很有用的工具。