实验内容
设计一个有 N个进程并发执行的进程调度程序
编写并调试一个模拟的进程调度程序,采用“轮转法”调度算法对五个进程进行调度。
轮转法原理
轮转法可以是简单轮转法、可变时间片轮转法,或多队列轮转法。
简单轮转法的基本思想是:所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果当前进程用完它的时间片后还未运行完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。
实验分析
FCFS:先来先服务调度算法,就是说那个进程先被调入到内存,就先分配资源给它,先执行这个进程。这个算法对长作业是有利的,但是对于短作业是不利的(就类比于去超市买东西,你就买一瓶水,但是要排很长的对),所以平均周转时间较长。
这里使用轮转法的基本思想就是:当你调入了几个进程到内存中来,他们都排成一个队列,我们均匀的给他们分配资源,但是在这里设置一个时间片。当时间片用完以后,该进程能完成执行,则进程执行完毕。如果时间片用完以后进程仍未执行完,就停止对该进程分配资源,并将该进程调入到就绪态队列的末尾。等待下一轮的分配。直到分配的次数够,分配的资源足够进程才能执行完。
源码实列
下面展示一些 内联代码片
。
在代码中实实现这一轮转法,我们需要运用数据结构中的链表,
通过链表来实现这一轮转。
周转时间=等待时间+处理时间
平均周转时间:各进程周转时间之和/进程数
代码
#include "stdio.h"
#include <stdlib.h>
#include <conio.h>
#define getpch(type) (type*)malloc(sizeof(type))
#define NULL 0
struct pcb { /* 定义进程控制块PCB */
char name[10]; //进程名
char state; //进程状态
int ntime; //进程需要处理的时间
int rtime; //已经处理的时间
int ztime;//周转时间
struct pcb* link; //将进程用链表的方式存放
}*ready=NULL,*p,*last;//声明头节点,和尾节点
int sum=0; //用于求周转时间的和
typedef struct pcb PCB;//声明结构体变量
void jump(){//跳转方法,如果时间片用完没有执行完进程,就放到就绪队列的最后
if(ready==NULL){//如果就绪队列为空
ready=p;
last=p;
}
else{ //就绪队列不为空时,把未执行完的进程放到队列最后
last->link=p;
last=p;
}
}
void input() /* 建立进程控制块函数*/
{
int i;
int num;
// clrscr(); /*清屏*/
printf("\n 请输入进程个数:");
scanf("%d",&num);
for(i=0;i<num;i++)
{
printf("\n 进程号No.%d:\n",i);
p=getpch(PCB);
printf("\n 输入进程名:");
scanf("%s",p->name);
printf("\n 输入进程运行时间:");
scanf("%d",&p->ntime);
printf("\n");
p->rtime=0;
p->ztime=0;
p->state='w';
p->link=NULL;
jump(); //调用jump函数
}
}
int space() //队列中进程的数目(链表的长度)
{
int l=0; PCB* pr=ready; //(pr为一个用于遍历的指针)
while(pr!=NULL)
{
l++;
pr=pr->link;
}
return(l);
}
void disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/
{
printf("\n qname \t state \t ntime \t rdtime \t ztime \n");
printf("|%s\t",pr->name);
printf("|%c\t",pr->state);
printf("|%d\t",pr->ntime);
printf("|%d\t",pr->rtime);
printf("|%d\t",pr->ztime);
printf("\n");
}
void check() /* 建立进程查看函数 */
{
PCB* pr;
printf("\n **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/
disp(p);
pr=ready;
printf("\n ****当前就绪队列状态为:\n"); /*显示就绪队列状态*/
while(pr!=NULL)
{
(pr->ztime)++;
disp(pr);
pr=pr->link;
}
}
void destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/
{
printf("\n 进程 [%s] 已完成.\n",p->name);
sum=sum+p->ztime;
free(p);
}
void running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/
{
(p->rtime)++;
(p->ztime)++;
if(p->rtime==p->ntime){
destroy(); /* 调用destroy函数*/
}
else
{
p->state='w';
jump(); /*调用jump函数*/
}
}
int main() /*主函数*/
{
int len,h=0;
float x;
char ch;
input();
len=space();
/* PCB *pr = ready;
while( pr!=NULL ) {
printf("ok ");
pr = pr->link;
}*/
while((len!=0)&&(ready!=NULL))
{
ch=getchar();
h++;
printf("\n The execute number:%d \n",h);
p=ready;
ready=p->link;
p->link=NULL;
p->state='R';
check();
running();
printf("\n 按任一键继续......");
ch=getchar();
}
x=(float)sum/len;
printf("平均周转时间:%.2f",x);
printf("\n\n 进程已经完成.\n");
ch=getchar();
}
有帮助的话,点个赞哦(^ _ ^)
Thanks!
版权声明:本文为m0_56145255原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。