您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 销售管理 > 东南大学-操作系统实验2-生产者-消费者问题
操作系统实验报告09010422何博伟2013年4月27日实验内容在Windows和Linux操作系统上,利用各自操作系统提供的Mutex和信号量机制(Win32API或Pthreads),实现生产者/消费者问题。具体要求见”OperatingSystemConcepts(SeventhEdition)”Chapter6后的Project(P236-241)。实验目的通过实验,理解Win32API、Pthreads中mutexlocks、semaphores等使用方法,并掌握如何利用它们实现进程(线程)间的同步和互斥。设计思路及流程图初始化信号量值(full,empty,mutex)利用系统调用,创建Producer和Consumer的线程若干Producer线程执行函数:do{…产生一个新的product…wait(empty);wait(mutex);…将新产生的product放入buffer中…signal(mutex);signal(full);}while(true);Consumer线程执行函数:do{wait(full)wait(mutex);…从buffer中移除一个product…signal(mutex);signal(empty);…对得到的product进行各种操作…}while(true);结束程序主程序流程图如下:Producer程序流程图如下:StartInitializesemaphoresInitializeProducer&ConsumerthreadsStartthreadsTerminatetheprogram.Waitfortermination…Consumer程序流程图如下:StartWaitforsemaphore:emptyInserttheproductintobufferWaitforsemaphore:mutexProduceanitemSignalsemaphore:mutexSignalsemaphore:full主要数据结构及其说明本程序主要用到bounded-buffer来存储缓存的数据,为方便起见,缓冲区中的内容为int类型。缓冲区主要结构如下图:StartWaitforsemaphore:fullRemoveaproductfrombufferWaitforsemaphore:mutexSignalsemaphore:mutexSignalsemaphore:emptyConsumetheproductfrontrear环形缓冲区,拥有front和rear两个指针,以及isEmpty一个布尔变量。其中front表示缓冲区的头部,rear表示缓冲区尾部,isEmpty表示缓冲区是否为空。插入一个元素时,改变isEmpty=true,如果尚未填满(front!=rear)并且插入后移动rear指针指向下一个空槽。删除元素时,先取出front指向的元素,然后将front往后移动一位,如果front==rear,则缓冲区空,置isEmpty=true。源程序及注释#ifdefWIN32#includeWindows.h#endif#ifdeflinux#includepthread.h#includesemaphore.h#endif#includeiostream#includemath.h#includetime.h#includestdlib.h//调用rand()及srand()函数usingnamespacestd;constintMAX_SEMAPHORE_VALUE=5;//a.k.aMAX_BUFFER_SIZEintbuffer[MAX_SEMAPHORE_VALUE];//bufferintfront=0,rear=0;boolisFull=false;constintWORKER_SIZE=20;inlinevoidPrintLineL(){coutendlEntertocontinue,Ctrl+Ctoquit.endl;;}inlinevoidPrintLineR(){coutendl;}boolAddToBuffer(intp){if(isFull){//Full.cerrBufferfull,cannotinsertp.endl;returnfalse;}buffer[rear]=p;cout[+]Insertedpintobuffer.endl;rear=(rear+1)%MAX_SEMAPHORE_VALUE;if(rear==front)isFull=true;returntrue;}intRemoveFromBuffer(){if(front!=rear||isFull){intr=buffer[front];cout[X]Removedrfrombuffer.endl;isFull=false;front=(front+1)%MAX_SEMAPHORE_VALUE;returnr;}else{//EmptycerrBufferempty!endl;return-1;}}#ifdefWIN32HANDLEfull,empty,mutex;voidinit_semaphores(){//InitializesemaphorescoutWin32OSdetected.Initializingsemaphores...endl;full=CreateSemaphore(NULL,0,MAX_SEMAPHORE_VALUE,NULL);empty=CreateSemaphore(NULL,MAX_SEMAPHORE_VALUE,MAX_SEMAPHORE_VALUE,NULL);mutex=CreateSemaphore(NULL,1,1,NULL);coutSemaphorescreated.endl;}DWORDWINAPIProducerProcess(LPVOIDarg){while(true){//PrintLine();//Produceanitemsrand(time(NULL));intproduct=rand()+GetCurrentThreadId();//coutProductproduced:productendl;//Waitingforemptybuffer...endl;//WaituntilbufferisemptyWaitForSingleObject(empty,INFINITE);//coutWaitingformutex...endl;//Waituntilthere'snomutexWaitForSingleObject(mutex,INFINITE);//AddtheproducttobufferPrintLineL();coutProducerGetCurrentThreadId()hasenteredcriticalsection.endl;AddToBuffer(product);PrintLineR();//Criticalthingsdone.ReleaseSemaphore(mutex,1,NULL);//coutMutexreleased...endl;ReleaseSemaphore(full,1,NULL);//coutFullsignaled...endl;cin.get();}}DWORDWINAPIConsumerProcess(LPVOIDarg){while(true){//PrintLine();//Waituntilbufferisfull//coutWaitingforbufferfull...endl;WaitForSingleObject(full,INFINITE);//Waituntilthere'snomutex//coutWaitingformutex...endl;WaitForSingleObject(mutex,INFINITE);//RemoveanitemfrombufferPrintLineL();coutConsumerGetCurrentThreadId()hasenteredcriticalsection.endl;intc=RemoveFromBuffer();//Criticalthingsdone.PrintLineR();ReleaseSemaphore(mutex,1,NULL);//coutMutexreleased...endl;ReleaseSemaphore(empty,1,NULL);//coutEmptysignaled...endl;//consumetheiteminccin.get();}}HANDLEthConsumers[WORKER_SIZE];HANDLEthProducers[WORKER_SIZE];constDWORDTIMEOUT=60000;voidinit_threads(){for(inti=0;iWORKER_SIZE;i++){//Createconsumerandworkerthreads.thConsumers[i]=CreateThread(NULL,0,ConsumerProcess,NULL,0,NULL);thProducers[i]=CreateThread(NULL,0,ProducerProcess,NULL,0,NULL);}coutThreadscreated.endl;WaitForMultipleObjects(WORKER_SIZE,thConsumers,TRUE,TIMEOUT);WaitForMultipleObjects(WORKER_SIZE,thProducers,TRUE,TIMEOUT);}#endif#ifdeflinux//Underlinuxsem_tfull,empty,mutex;voidinit_semaphores(){coutLinuxdetected.Initializingsemaphores...endl;//sem_init()初始化一个定位在sem的匿名信号量。value参数指定信号量的初始值。pshared参数指明信号量是由进程内线程共享,还是由进程之间共享。如果pshared的值为0,那么信号量将被进程内的线程共享,并且应该放置在所有线程都可见的地址上(如全局变量,或者堆上动态分配的变量)。//full=0,empty=n,mutex=1sem_init(&full,0,0);sem_init(&empty,0,MAX_SEMAPHORE_VALUE);sem_init(&mutex,0,1);coutSemaphorescreated.endl;}void*ProducerProcess(void*arg){while(true){//Produceanitemsrand(time(NULL));intproduct=rand()%32767+pthread_self()%32767;//Waitforemptysignal..sem_wait(&empty);//Waitformutexsignal..sem_wait(&mutex);/*Enteredcriticalsection*/PrintLineL();coutProducerpthread_self()hasenteredcriticalsection.endl;AddToBuffer(
本文标题:东南大学-操作系统实验2-生产者-消费者问题
链接地址:https://www.777doc.com/doc-4906460 .html