请编写一个程序,模拟若干进程调度执行的情况。假设进程的状态分为执行和就绪两种。每个进程以其PCB为代表即可,无需创建真正的进程。以链表的方式组织PCB,分为三个队列:
freeQueue:一个空白PCB队列
readyQueue:一个就绪队列
runningQueue:一个执行队列
程序开始运行时,用户输入进程数量n,以及每个进程需要运行的时间t0/t1/…/tn。程序从空白PCB队列中取出PCB创建进程,插入readyQueue。
进程的调度采用随机的方式,即从就绪队列中随机选择一个进程投入运行(就是将该PCB中的状态变量赋值为“运行”)。相应的修改其所在队列,并且原来处于运行态的进程需要转变为“就绪”态,插入readyQueue。
假设时间片是2,进程每次调度运行后,其还需运行的时间应该减少2,直至为0,即表示该进程执行完毕。需要回收PCB到freeQueue。
每次发生调度的时候,需要打印信息示例:
Sched: P0(Running -> Ready), P3(Ready -> Running)
Running: P3
Ready: P1->P2->P0
上述信息表示调度时P0处于运行态,选择P3运行,P0进程的PCB进入就绪队列,并且在队尾。就绪队列是按照队列节点次序输出进程名称。
示例片段代码:
#define free 0
#define ready 1
#define running 2
#define ts 2 /* time slice */
struct PCB {
int pid;
int pstate;
char *pname;
int ptime;
struct PCB *pnext;
}
写了挺久,各种关系虽然不是很复杂,但是很费时间。进程调度以及三个队列的关系等等要想明白,里面有许多坑我也踩过,做过了感觉心满意足,贴出来分享下
struct pcb{
int pid;//进程id
int pstate; //进程状态
char pname[20];//映像名字
int ptime;//剩余运行时间
struct pcb *next;
};
void addTofreeQueue(struct pcb *freeQueue,int i);//创建空白pcb
void freeToready(struct pcb *freeQueue,struct pcb *readyQueue);//把创建好的空白pcb存入到ready对列中
void readyTorun(struct pcb *readyQueue,struct pcb *runningQueue);//ready队列中的进程调度到run队列
void running(struct pcb *p,struct pcb *runningQueue);//对ready队列传递过去的pcb进行操作,并输出结果
void runningToready(struct pcb *m,struct pcb *readyQueue);//时间片到达将进程调度到readyQueue
void runningTofree(struct pcb *m,struct pcb *freeQueue);//时间片到达将进程调度到freeQueue
void ptf(struct pcb *readyQueue);//将readyQueue队列中的进程名称逐个输出
struct pcb *freeQueue=(struct pcb*)malloc(sizeof(struct pcb));
struct pcb *readyQueue=(struct pcb*)malloc(sizeof(struct pcb));
struct pcb *runningQueue=(struct pcb*)malloc(sizeof(struct pcb));
int main(){
freeQueue->next=NULL;
readyQueue->next=NULL;
runningQueue->next=NULL;
printf("请输入进程数量 n:");
int n,flag=1,t,j=1;
char str[10];
scanf("%d",&n);
printf("每个进程运行使用的时间:
");
struct pcb *m,*p;
for(int i=0;iwhile(p->next)
p=p->next;
m=(struct pcb*)malloc(sizeof(struct pcb));
m->pid=i;
m->pstate=0;
sprintf(str,"%d",i);
memset(m->pname,0,20);
m->pname[0]='p';
strcat(m->pname,str);
scanf("%d",&m->ptime);
p->next=m;
m->next=NULL;
}
freeToready(freeQueue,readyQueue);
while(flag){
printf("第%d次运行
",j);
t=0;
readyTorun(readyQueue,runningQueue);
p=readyQueue;
while(p->next){
t+=p->ptime;
p=p->next;
}
if(t==0)
flag=0;
j++;
}
return 0;
}
void freeToready(struct pcb *freeQueue,struct pcb *readyQueue){
//把freeQueue队列中的元素全部送入就绪队列中 ,这里可以直接readyQueue->next=freeQueue->next
struct pcb *f,*p;
p=freeQueue->next;
f=readyQueue;
while(p){
freeQueue->next=p->next;
while(f->next)
f=f->next;
f->next=p;
p->next=NULL;
p->pstate=1;
p=freeQueue->next;
}
}
void readyTorun(struct pcb *readyQueue,struct pcb *runningQueue){
//随机把一个在readyQueue队列中的pcb调度到running队列中
int random,length=0;
struct pcb *f,*p;
f=readyQueue->next;
while(f){//求readyQueue里面进程的数量
length++;
f=f->next;
}
if(length==0){//判断readyQueue中是否还有进程存在
printf("进程运行完了");
}
else{
p=readyQueue;
srand(time(0));
random=rand()%(length+1);//防止最后一个pcb不能运行
if(random==0)//防止pcb是readyQueue自己 ,readyQueue真是害人
random++;
for(int i=0;i//生成随机数
p=p->next;//随机生成指向一个在readyQueue队列中的一个元素
}
f=readyQueue;
while(f->next!=p)
f=f->next;
f->next=p->next;
running(p,runningQueue); //把指到的pcb传入到running中
}
}
void running(struct pcb *p,struct pcb *runningQueue){//接受来自readyQueue队列的进程
struct pcb *m;
if(runningQueue->next==NULL){
runningQueue->next=p;
p->next=NULL;
p->pstate=2;
printf("第一个进程进入running队列,cpu开始工作
");
printf("%s(Ready->Running)
",p->pname);
printf("Running:%s
",p->pname);
p->ptime-=2;
if(p->ptime>0){
runningToready(p,readyQueue);
}
else{
runningTofree(p,freeQueue);
}
}
else{
m=runningQueue->next;
m->ptime-=2;
if(m->ptime>0){
runningToready(m,readyQueue);
}
else{
runningTofree(m,freeQueue);
}
runningQueue->next=p;
p->pstate=2;
p->next=NULL;
printf("Sched: %s(Running -> Ready),%s(Ready->Running)
",m->pname,p->pname);
printf("Running:%s
",p->pname);
}
ptf(readyQueue);
}
void runningToready(struct pcb *m,struct pcb *readyQueue){
//将没完成的进程调回到readyQueue队列
printf("进入runningToready
");
struct pcb *p;
p=readyQueue;
while(p->next){
p=p->next;
}
p->next=m;
m->next=NULL;
m->pstate=1;
}
void runningTofree(struct pcb *m,struct pcb *freeQueue){
//把不需要运行时间的进程放到freeQueue
struct pcb *p;
p=freeQueue;
while(p->next){
p=p->next;
}
m->next=p->next;
m->next=NULL;
}
void ptf(struct pcb *readyQueue){
struct pcb *p;
int flag=1;
p=readyQueue->next;
while(p){
if(flag==1){
printf("%s",p->pname);
flag=0;
}
else{
printf("->%s",p->pname);
}
p=p->next;
}
printf("
");
}
?