#include<stdio.h>
#include<stdlib.h> //有用到malloc()
#include<conio.h> //键盘输入
#include<windows.h>
#define getpch(type) (type*)malloc(sizeof(type))
#define NULL 0
struct pcb //定义进程控制块
{
char name[10]; //定义进程名
char state; //进程状态
int super; //进程优先级
int rtime; //已经运行时间
int ntime; //运行所需时间
struct pcb* link; //定义一个队列指针,定义了一个指向pcb结构类型的指针link作为自己的成员函数
}*ready=NULL,*p; //定义两个指向pcb结构指针类型的指针ready和p,ready的初值为空,并建立了一个空的就绪队列
typedef struct pcb PCB; //定义将struct pcb称为PCB
//***********************************************************************************************
void sort() //建立对进程进行优先级排列的函数
{
PCB *f,*s; //定义两个用来排列的指针first和second
int insert=0; //插入
if((ready==NULL)||(p->super)>(ready->super)) //比较优先级,优先级最大者,直接插入队首
{
p->link=ready; //
ready=p; // 将新建进程放入队首
}
else //比较进程的优先级,并将其插入适当的地方
{
f=ready; //
s=f->link; //插入新的进程
while(s!=NULL) //如果第二个进程不为空
{
if((p->super)>(s->super)) //将插入进程与当前进程比较
{ //如果插入进程的优先级大于当前进程优先级,则插入当前优先级的前面
p->link=s;
f->link=p;
s=NULL;
insert=1;
}
else //否则,将新插入的进程插入到当前进程的后面,向后移指针
{
f=f->link;
s=s->link;
}
}
if(insert==0)
f->link=p; //将p指针指向队尾
}
}
//**********************************************************************************
void input() //建立进程控制块函数
{
int i,num;
printf("*********************最高优先级优先算法**********************");
printf("\n 请输入进程的数量:");
scanf("%d",&num); //键盘上输入
for(i=1;i<=num;i++)
{
printf("\n 进程号No.%d:",i);
p=getpch(PCB);
printf("\n 请输入进程名:");
scanf("%s",p->name);
printf("\n 请输入进程优先级:");
scanf("%d",&p->super);
printf("\n 请输入进程所需运行时间:");
scanf("%d",&p->ntime);
printf("\n");
p->rtime=0;
p->state='w';
p->link=NULL;
sort(); //调用sort函数进行排序
}
}
//********************************************************************************
int space() //计算进程控制块个数的函数
{
int k=0;
PCB*pr=ready; //pr指向队首进程
while(pr!=NULL) //pr为空则说明计数完成,就绪队列没到头,就一直输出
{
k++;
pr=pr->link;
}
printf(" 进程数量:%d\n",k);
printf("*********************************************\n");
return(k);
}
//************************************************************************************
void disp(PCB*pr) //建立进程显示函数,显示当前的进程
{
printf("\n name\t state\t super \t ntime\t rtime\n");
printf(" %s \t",pr->name);
printf(" %c \t",pr->state);
printf(" %d \t",pr->super);
printf(" %d \t",pr->ntime);
printf(" %d \t",pr->rtime);
printf("\n");
}
//****************************************************************************
void check() //建立进程查看函数,查看已经排列好的情况
{
PCB* pr;
printf("\n 当前正在运行的进程:%s",p->name);
disp(p); //调用disp()显示已经筛选出来的正在运行的进程
pr=ready;
printf("\n 当前就绪队列状态为:\n");
while(pr!=NULL)
{
disp(pr); //调用disp()显示已经排列好的就绪队列
pr=pr->link;
}
}
void destroy() //建立函数,撤销进程
{
printf("\n 进程[%s]已完成.\n",p->name);
free(p); //释放空间
}
//********************************************************************************
void running() //建立进程就绪函数(进程运行时间到,置为就绪状态)
{
(p->rtime)++; //运行时间加一
if(p->rtime==p->ntime)
destroy(); //
else
{
(p->super)--; //运行时间减一
p->state='w';
sort(); //调用一次之后,运行时间时间和运行状态改变后,重新去排序进程
}
}
//***************************************************************************
void main() //主函数
{
int len,h=0; //h是用于计算执行次数的
char ch;
input(); //调用input函数输入相关的进程信息
len=space(); //input调用完之后,回到主函数调用space函数得到对列长度
while((len!=0)&&(ready!=NULL))
{
ch=getchar(); //从键盘输入一个字符型数据,把值赋给变量ch,这个是为了每一次被执行,自己手动回车呈现出来,如果没有,则会一次性出现全部被执行的情况
h++;
printf("\n The execute number:%d \n",h);
p=ready;
ready=p->link;
p->link=NULL;
p->state='R';
check(); //调用显示正在运行的函数和就绪的函数
running(); // 调用进程就绪函数,上一个正在运行的进程运行完之后,运行时间加1,将就绪队列里面优先级最高的进程置为运行状态,如果是同优先级,则看哪个先进来,这个不可以运行在check()前,会导致多计算,并出现错误
printf("\n 请回车继续......");
ch=getchar();
}
printf("\n\n 进程已经完成.\n");
ch=getchar();
}