操作系统作业2

2019-07-14 09:00发布

请编写一个程序,模拟若干进程调度执行的情况。假设进程的状态分为执行和就绪两种。每个进程以其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; /* 进程ID */ int pstate; /* 进程状态 */ char *pname; /* 映象名称 */ int ptime; /* 剩余运行时间 */ struct PCB *pnext; /* 下一个PCB */ } 写了挺久,各种关系虽然不是很复杂,但是很费时间。进程调度以及三个队列的关系等等要想明白,里面有许多坑我也踩过,做过了感觉心满意足,贴出来分享下 #include #include #include #include #include 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(" "); } ?