《操作系统》实验指导书吉林农业大学信息技术学院2007年8月-1-实验一:进程管理实验学时:2实验类型:验证一、实验目的了解生产者与消费者在实现进程同步过程中的解决方案。二、实验步骤数据结构:每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程类型标号、进程系统号、进程状态(本程序未用)、进程产品(字符)、进程链指针等等。系统开辟了一个缓冲区,大小由buffersize指定。程序中有三个链队列,一个链表。一个就绪队列(ready),两个等待队列:生产者等待队列(producer);消费者队列(consumer)。一个链表(over),用于收集已经运行结束的进程。本程序通过函数模拟信号量的原子操作。算法的文字描述:①由用户指定要产生的进程及其类别,存入进入就绪队列。②调度程序从就绪队列中提取一个就绪进程运行。如果申请的资源不存在则进入响应的等待队列,调度程序调度就绪队列中的下一个进程。进程运行结束时,会检查对应的等待队列,激活队列中的进程进入就绪队列。运行结束的进程进入over链表。重复这一过程直至就绪队列为空。③程序询问是否要继续?如果要转开始执行,否则退出程序。源程序:#includestdio.h#includestdlib.h#definebuffersize5intprocessnum=0;/*定义进程控制块PCB*/structpcb{intflag;//flag=1denoteproducer;flag=2denoteconsumer;intnumlabel;charproduct;-2-charstate;structpcb*processlink;}*exe=NULL,*over=NULL;typedefstructpcbPCB;PCB*readyhead=NULL,*readytail=NULL;PCB*consumerhead=NULL,*consumertail=NULL;PCB*producerhead=NULL,*producertail=NULL;//产品数量intproductnum=0;intfull=0,empty=buffersize;//semaphorecharbuffer[buffersize];//缓冲区intbufferpoint=0;//缓冲区指针voidlinkqueue(PCB*process,PCB**tail);PCB*getq(PCB*head,PCB**tail);boolhasElement(PCB*pro);voiddisplay(PCB*p);voidlinklist(PCB*p,PCB*listhead);voidfreelink(PCB*linkhead);boolprocessproc();boolwaitempty();boolwaitfull();voidsignalempty();voidsignalfull();voidproducerrun();voidcomsuerrun();boolhasElement(PCB*pro);voidlinklist(PCB*p,PCB*listhead){PCB*cursor=listhead;while(cursor-processlink!=NULL){cursor=cursor-processlink;}cursor-processlink=p;}voidfreelink(PCB*linkhead){PCB*p;while(linkhead!=NULL){p=linkhead;linkhead=linkhead-processlink;free(p);}}voidlinkqueue(PCB*process,PCB**tail)-3-{if((*tail)!=NULL){(*tail)-processlink=process;(*tail)=process;}else{printf(队列未初始化!);}}PCB*getq(PCB*head,PCB**tail){PCB*p;p=head-processlink;if(p!=NULL){head-processlink=p-processlink;p-processlink=NULL;if(head-processlink==NULL)(*tail)=head;}elsereturnNULL;returnp;}boolprocessproc(){inti,f,num;charch;PCB*p=NULL;PCB**p1=NULL;printf(\n请输入希望产生的进程个数?);scanf(%d,&num);getchar();for(i=0;inum;i++){printf(\n请输入您要产生的进程:输入1为生产者进程;输入2为消费者进程\n);scanf(%d,&f);getchar();p=(PCB*)malloc(sizeof(PCB));if(!p){printf(内存分配失败);returnfalse;}-4-p-flag=f;processnum++;p-numlabel=processnum;p-state='w';p-processlink=NULL;if(p-flag==1){printf(您要产生的进程是生产者,它是第%d个进程。请您输入您要该进程产生的字符!\n,processnum);scanf(%c,&ch);getchar();p-product=ch;productnum++;printf(您要该进程产生的字符是%c\n,p-product);}else{printf(您要产生的进程是消费者,它是第%d个进程。\n,p-numlabel);}linkqueue(p,&readytail);}returntrue;}boolwaitempty(){if(empty=0){printf(进程%d:缓冲区存数,缓冲区满,该进程进入生产者等待队列\n,exe-numlabel);linkqueue(exe,&producertail);returnfalse;}else{empty--;returntrue;}}voidsignalempty(){PCB*p;if(hasElement(producerhead)){p=getq(producerhead,&producertail);linkqueue(p,&readytail);printf(等待中的生产者进程进入就绪队列,它的进程号是%d\n,p-numlabel);}-5-empty++;}boolwaitfull(){if(full=0){printf(进程%d:缓冲区取数,缓冲区空,该进程进入消费者等待队列\n,exe-numlabel);linkqueue(exe,&consumertail);returnfalse;}else{full--;returntrue;}}voidsignalfull(){PCB*p;if(hasElement(consumerhead)){p=getq(consumerhead,&consumertail);linkqueue(p,&readytail);printf(等待中的消费者进程进入就绪队列,它的进程号是%d\n,p-numlabel);}full++;}voidproducerrun(){if(!waitempty())return;printf(进程%d开始向缓冲区存数%c\n,exe-numlabel,exe-product);buffer[bufferpoint]=exe-product;bufferpoint++;printf(进程%d向缓冲区存数操作结束\n,exe-numlabel);signalfull();linklist(exe,over);}voidcomsuerrun(){if(!waitfull())return;printf(进程%d开始向缓冲区取数\n,exe-numlabel);exe-product=buffer[bufferpoint-1];bufferpoint--;printf(进程%d向缓冲区取数操作结束,取数是%c\n,exe-numlabel,exe-product);signalempty();-6-linklist(exe,over);}voiddisplay(PCB*p){p=p-processlink;while(p!=NULL){printf(进程%d,它是一个,p-numlabel);p-flag==1?printf(生产者\n):printf(消费者\n);p=p-processlink;}}boolhasElement(PCB*pro){if(pro-processlink==NULL)returnfalse;elsereturntrue;}voidmain(){charterminate;boolelement;printf(你想开始程序吗?(y/n));scanf(%c,&terminate);getchar();//Queueinitialize;readyhead=(PCB*)malloc(sizeof(PCB));if(readyhead==NULL)return;readytail=readyhead;readyhead-flag=3;readyhead-numlabel=processnum;readyhead-state='w';readyhead-processlink=NULL;consumerhead=(PCB*)malloc(sizeof(PCB));if(consumerhead==NULL)return;consumertail=consumerhead;consumerhead-processlink=NULL;consumerhead-flag=4;consumerhead-numlabel=processnum;consumerhead-state='w';consumerhead-processlink=NULL;producerhead=(PCB*)malloc(sizeof(PCB));if(producerhead==NULL)return;producertail=producerhead;producerhead-processlink=NULL;-7-producerhead-flag=5;producerhead-numlabel=processnum;producerhead-state='w';producerhead-processlink=NULL;over=(PCB*)malloc(sizeof(PCB));if(over==NULL)return;over-processlink=NULL;while(terminate=='y'){if(!processproc())break;element=hasElement(readyhead);while(element){exe=getq(readyhead,&readytail);printf(进程%d申请运行,它是一个,exe-numlabel);exe-flag==1?printf(生产者\n):printf(消费者\n);if(exe-flag==1)producerrun();elsecomsuerrun();element=hasElement(readyhead);}printf(就绪队列没有进程\n);if(hasElement(consumerhead)){printf(消费者等待队列中有进程:\n);display(consumerhead);}else{printf(消费者等待队列中没有进程\n);}if(hasElement(producerhead)){printf(生产者等待队列中有进程:\n)