/*进程调度程序采用静态数组、链接方式,有就绪队列,阻塞队列,
就绪队列指针,阻塞队列指针,和执行指针。*/
#include <malloc.h>
#include <memory.h>
#include <stdio.h>
#define NULL 0
#define M 10 //pcb数组中的最大个数
typedef struct node
{ int id; //进程id号
int pr; //进程优先级
int ct; //进程已经运行时间片个数
int at; //进程还需多少运行时间片个数
int bt; //进程需要阻塞的时间片的个数
int sb; //进程运行多少时间片后进入阻塞
struct node *next;
} jd;
/*寻找就绪队列中进程优先级最大的
并将其从就绪队列中移出返回给运行指针*/
jd *max(jd *p)
{
jd *maxnode=NULL,*p1,*p2,*p3=p;
int maxnum;
p1=p; p2=p;
if(p->next==NULL)
return NULL;
maxnum=p->next->pr;
while(p1->next!=NULL)
{ p2=p1->next;
if(maxnum <= p2->pr)
{ maxnode=p2;
p3=p1; //p3指向就绪队列中优先级最大的接点的上一级
maxnum=p2->pr;
}
p1=p1->next;
}
p3->next=maxnode->next;
maxnode->next=NULL;//将就绪队列中优先级最大的接点移出就绪队列
return maxnode;
}
//将阻塞队列中需要进入就绪队列的pcb添加到就绪队列
void blocktoready(jd *pblock,jd *pready)
{
jd *p1=pblock,*p3;
while(p1->next!=NULL)
{
p3=p1->next;
if(p3->bt==0)
{ p1->next=p3->next;
p3->next=pready->next;
pready->next=p3;
}
p1=p1->next;
if(p1==NULL)
break;
}
}
//修改就绪队列的pcb中相应的值
void ready(jd *p)
{ jd *p1=p->next;
while(p1!=NULL)
{
p1->pr++;
p1=p1->next;
}
}
//修改运行队列的pcb中相应的值
void run(jd *p)
{ jd *p1;
if(p->next!=NULL)
{
p1=p->next;
p1->pr=-3;
p1->at--;
p1->ct++;
}
}
//修改阻塞队列的pcb中相应的值
void block(jd *p)
{ jd *p1=p->next;
while(p1!=NULL)
{
p1->bt--;
p1=p1->next;
}
}
//判断将运行完一个时间片的进程插入就绪队列、阻塞队列、还是完成释放
void runtoreadyorblock(jd *prun,jd *pready,jd *pblock)
{ jd *p;
if(prun->next==NULL)
return;
p=prun->next;
if(p->at==0)
prun->next=NULL;
else
{
if(p->ct==p->sb)
{ p->next=pblock->next;
pblock->next=p;
prun->next=NULL;
}
else{
p->next=pready->next;
pready->next=p;
prun->next=NULL;
}
}
}
//创建pcb链接队列
jd *head(jd pcb[],int l)
{
int i;
for(i=0;i<l;i++)
{
printf("请输入pcb%d的信息\n",i);
printf("PRIORITY:");
scanf("%d",&pcb[i].pr);
printf("ALLTIME:");
scanf("%d",&pcb[i].at);
printf("STARTBLOCK:");
scanf("%d",&pcb[i].sb);
printf("BLOCKTIME:");
scanf("%d",&pcb[i].bt);
pcb[i].id=i;
pcb[i].ct=0;
}
for(i=0;i<l-1;i++)
{
pcb[i].next=&pcb[i+1];
}
pcb[l-1].next=NULL;
return &pcb[0];
}
//打印信息子函数
void print(jd *p)
{ jd *p1;
if(p->next==NULL)
printf("\t\t该队列为空.\n");
while(p->next!=NULL)
{
p1=p->next;
printf("\t\t%d\t%d\t%d\t%d\t%d\t%d\n",p1->id,p1->pr,p1->ct,p1->at,p1->sb,p1->bt);
p=p->next;
if(p==NULL)
break;
}
}
void main()
{
jd pcb[M];
jd *pready=(jd *)malloc(sizeof(jd));
jd *prun=(jd *)malloc(sizeof(jd));
jd *pblock=(jd *)malloc(sizeof(jd));
int l,i,n=1;
pready->next=NULL;
prun->next=NULL;
pblock->next=NULL;
printf("请输入需要运行进程的个数:\n");
scanf("%d",&l);
pready->next=head(pcb,l);
while(1)
{
prun->next=max(pready);
run(prun);
ready(pready);
block(pblock);
printf("运行时间片%d中各个队列pcb的信息:\n",n);
printf("\t\tid\tpr\tct\tat\tsb\tbt\n");
printf("the ready pcb:\n");
print(pready); //打印就绪队列各pcb信息
printf("the run pcb:\n");
print(prun); //打印运行pcb信息
printf("the block pcb:\n");
print(pblock); //打印阻塞队列各pcb信息
printf("the all pcb:\n"); //打印所有的pcb信息
for(i=0;i<l;i++)
{
printf("\t\t%d\t%d\t%d\t%d\t%d\t%d\n ",pcb[i].id,pcb[i].pr,pcb[i].ct,pcb[i].at,pcb[i].sb,pcb[i].bt);
}
printf("\n");
blocktoready(pblock,pready);
runtoreadyorblock(prun,pready,pblock);
n++;
if(pready->next==NULL && pblock->next==NULL)//阻塞队列和就绪队列都为空则结束
break;
}
}