#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define getpch(type) (type*)malloc(sizeof(type)) //将申请内存空间函数自定义为getpch(type)
#define Robin 5 //定义时间片为5
struct pcb{ //定义进程控制块的结构
char name[10]; //进程名称
char state; //进程状态
int super; //进程优先级
int ntime; //进程总共需要的cpu时间
int rtime; //进程已近使用cpu的时间
struct pcb* link; //进程指向下一个进程的指针
}*ready=NULL, *p; //ready表示指向就绪队列中首元素的指针,初始化为NULL,p用来存放当前刚输入的PCB
typedef struct pcb PCB; //自定义PCB结构体
//*******************************PCB排序模块***********************************
//按照FIFO原则,轮流调度队列中的作业,最先进的放在队首,最后进的放在队尾
void sort()
{
PCB *first, *second;
int insert=0; //insert用于记录当前PCB p是否插在就绪队列的尾部
if((ready==NULL)||((p->super)>(ready->super))) //如果就绪队列为空或当前process的super比就绪队列中的第一各元素大,则:
{ //注:就绪队列中的元素按优先级从高到低排的
p->link=ready; //把P放在队首,并且让ready指向p
ready=p;
}
else //就绪队列不为空,p的super不比首元素大,那就循环进行比较
{
first=ready;
second=first->link; //first和second都是两个用于循环的变量
while(second!=NULL) //一直比较到就绪队列的末尾
{
if((p->super)>(second->super)) //当前进程的优先级大于原就绪队列中second所指向的元素时,就把p插入到first和second所指向的元素之间
{
p->link=second;
first->link=p;
second=NULL;
insert=1; //插入队列记录符号
}
else
{
first=first->link; //两个循环变量继续后移,为下一轮循环做准备
second=second->link;
}
}
if(insert==0) first->link=p; //循环到最后了,如果insert仍为0的话,就把P放在队尾
}
}
//*******************************PCB输入模块*********************************************
void input()
{
int i,num;
printf("\nPlease input the number of processes:");
scanf("%d",&num);
for(i=0;i<num;i++)
{
printf("\nProcess NO.%d:\n",i);
p=getpch(struct pcb);
printf("\nInput the name of the process:");
scanf("%s",p->name);
/*printf("\nInput the priority of the process:");
scanf("%d",&p->super);*/ //不需要知道优先级
printf("\nInput the running time of the process:");
scanf("%d",&p->ntime);
printf("\n");
p->rtime=0;
p->state='w'; //所有进程的初始状态都是等待状态
p->link=NULL; //防止不定指针
p->super=20; //让所有进程的优先级相同且为20(用的还是您的优先级排序的算法,当是实际运行的是FIFO算法)
sort();
}
}
//*******************************PCB就绪队列中元素计数模块********************************
int space() //计算就绪队列中PCB的总数
{
int l=0;
PCB *pr=ready; //获取就绪队列的头指针ready
while(pr!=NULL) //循环计数
{
l++;
pr=pr->link;
}
return(l);
}
//*******************************打印PCB信息模块*****************************************
void disp(PCB *pr)
{
printf("\nqname\tstate\tndtime\t had run time\n");
printf("|%s\t",pr->name);
printf("|%c\t",pr->state);
//printf("|%d\t\t",pr->super);
printf("|%d\t\t",pr->ntime);
printf("|%d\t",pr->rtime);
printf("\n");
}
//****************************检查当前有哪些进程在运行,那些处于wait状态*******************************
void check()
{
PCB *pr;
printf("\n *********The current running process is: %s\n",p->name);
disp(p);
pr=ready;
printf("\n *********The state of the Waiting List:\n");
while(pr!=NULL) //打印其它等待的进程
{
disp(pr);
pr=pr->link;
}
}
//*******************************打印已经完成的进程并释放内存空间**********************************
void destroy()
{
printf("\nAfter this dispatch ,the process [%s] will finish.\n",p->name);
free(p);
}
//*****************************进行时间片轮转*******************************
void running()
{
(p->rtime)+=Robin; //Robin为时间片大小(常量),
if(p->rtime==p->ntime) //如果执行时间和该进程所需时间相等 则撤销该进程
destroy();
else //未执行完毕则优先级减一并将状态改为w
{
(p->super)--;
p->state='w';
sort(); //加入队列并重新排序
}
}
//*******************************主函数模块*************************************************
void main() //主函数
{
int len, h=0; //h表示进程调度的次数,每调度一次,h++
char ch;
input(); //输入程序
len=space(); //获取就绪队列长度
while((len!=0)&&(ready!=NULL))
{
ch=getchar();
h++;
printf("\n The execute number: %d \n",h);
p=ready; //以下三行是将P从就绪队列的队首摘除
ready=p->link;
p->link=NULL;
p->state='R'; //将P的状态改为R
check();
running();
printf("\nProcess Any Key to Continue...");
ch=getchar();
}
printf("\n\nAll the processes has finished running");//所有进程已经完成
ch=getchar();
}
- 1
- 2
前往页