您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 操作系统实验第六讲进程的同步
操作系统实验报告课程名称操作系统实验实验项目名称进程的同步学号班级20120616姓名专业计算机科学与技术学生所在学院计算机科学与技术学院指导教师初妍实验室名称地点21#428哈尔滨工程大学计算机科学与技术学院1一、实验概述1.实验名称进程的同步2.实验目的使用EOS的信号量,编程解决生产者—消费者问题,理解进程同步的意义。调试跟踪EOS信号量的工作过程,理解进程同步的原理。修改EOS的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。3.实验类型验证+设计4.实验内容3.1准备实验3.2使用EOS的信号量解决生产者-消费者问题3.3调试EOS信号量的工作过程3.3.1创建信号量3.3.2等待、释放信号量3.3.2.1等待信号量(不阻塞)3.3.2.2释放信号量(不唤醒)3.3.2.3等待信号量(阻塞)3.3.2.4释放信号量(唤醒)3.4修改EOS的信号量算法二、实验环境操作系统windosxp编译器OSLab语言c语言2三、实验过程1.设计思路和流程图准备实验使用EOS的信号量解决生产者-消费者问题调试EOS信号量的工作过程创建信号量释放信号量(唤醒)等待信号量(阻塞)释放信号量(不唤醒)等待信号量(不阻塞)等待释放信号量修改EOS的信号量算法结束实验33.需要解决的问题及解答(1)生产者在生产了13号产品后本来要继续生产14号产品,可此时生产者为什么必须等待消费者消费了4号产品后,才能生产14号产品呢?生产者和消费者是怎样使用同步对象来实现该同步过程的呢?答:这是因为临界资源的限制。临界资源的数值范围是0到10,只有当临界main函数开始创建Mutex对象创建Empty信号量对象创建Full信号量对象创建生产者线程创建消费者线程等待生产者线程和消费者线程结束关闭句柄main函数结束Producer函数开始生产完毕?等待Empty信号量对象等待Mutex对象生产一个产品,占用一个缓冲区循环向后移动缓冲区指针释放Mutex对象释放Full信号量对象等待500毫秒Producer函数结束Consumer函数开始消费完毕毕?等待Full信号量对象等待Mutex对象消费一个产品,清空一个缓冲区循环向后移动缓冲区指针释放Mutex对象释放Empty信号量对象前10个产品?等待2000毫秒等待100毫秒Consumer函数结束4资源不满10时才能让生产者生产东西,每次生产一个临界资源数量加一,当临界资源数值到10时,无法继续生产,所以它必须等到消费者,消耗掉一个,临界资源数值才会减一并腾出空间,才能继续生产14号产品。(2)修改EOS的信号量算法修改PsWaitForSemaphore函数:PsWaitForSemaphore(INPSEMAPHORESemaphore,INULONGMilliseconds)/*++功能描述:信号量的Wait操作(P操作)。参数:Semaphore--Wait操作的信号量对象。Milliseconds--等待超时上限,单位毫秒。返回值:STATUS_SUCCESS。当你修改信号量使之支持超时唤醒功能后,如果等待超时,应该返回STATUS_TIMEOUT。--*/{BOOLIntState;STATUSflag;//保存不同情况下的返回值,ASSERT(KeGetIntNesting()==0);//中断环境下不能调用此函数。IntState=KeEnableInterrupts(FALSE);//开始原子操作,禁止中断。if(Semaphore-Count0){Semaphore-Count--;flag=STATUS_SUCCESS;}//如果信号量大于零,说明尚有资源,可以为线程分配elseflag=PspWait(&Semaphore-WaitListHead,Milliseconds);KeEnableInterrupts(IntState);//原子操作完成,恢复中断。returnflag;}修改PsReleaseSemaphore函数:5PsReleaseSemaphore(INPSEMAPHORESemaphore,INLONGReleaseCount,OUTPLONGPreviousCount)/*++功能描述:信号量的Signal操作(V操作)。参数:Semaphore--Wait操作的信号量对象。ReleaseCount--信号量计数增加的数量。当前只能为1。当你修改信号量使之支持超时唤醒功能后,此参数的值能够大于等于1。PreviousCount--返回信号量计数在增加之前的值。返回值:如果成功释放信号量,返回STATUS_SUCCESS。--*/{STATUSStatus;BOOLIntState;IntState=KeEnableInterrupts(FALSE);//开始原子操作,禁止中断。if(Semaphore-Count+ReleaseCountSemaphore-MaximumCount){Status=STATUS_SEMAPHORE_LIMIT_EXCEEDED;}else{//记录当前的信号量的值。if(NULL!=PreviousCount){*PreviousCount=Semaphore-Count;}intmm=Semaphore-Count;while((!ListIsEmpty(&Semaphore-WaitListHead))&&(ReleaseCount)){PspWakeThread(&Semaphore-WaitListHead,STATUS_SUCCESS);PspThreadSchedule();ReleaseCount--;}Semaphore-Count=mm+ReleaseCount;//可能有线程被唤醒,执行线程调度。Status=STATUS_SUCCESS;}KeEnableInterrupts(IntState);//原子操作完成,恢复中断。returnStatus;}6(3)绘制ps/semaphore.c文件内PsWaitForSemaphore和PsReleaseSemaphore函数的流程图。PsWaitForSemaphore函数流程PsReleaseSemaphore函数流程5.源程序并附上注释//缓冲池。#defineBUFFER_SIZE10intBuffer[BUFFER_SIZE];//产品数量。#definePRODUCT_COUNT30//用于生产者和消费者同步的对象句柄。HANDLEMutexHandle;HANDLEEmptySemaphoreHandle;HANDLEFullSemaphoreHandle;//生产者和消费者的线程函数ULONGProducer(PVOIDParam);ULONGConsumer(PVOIDParam);intmain(intargc,char*argv[]){HANDLEProducerHandle;HANDLEConsumerHandle;#ifdef_DEBUG__asm(int$3\nnop);#endif//创建用于互斥访问缓冲池的Mutex对象。MutexHandle=CreateMutex(FALSE,NULL);if(NULL==MutexHandle){return1;7}//创建Empty信号量,表示缓冲池中空缓冲区数量。初始计数和最大计数都为BUFFER_SIZE。//EmptySemaphoreHandle=CreateSemaphore(BUFFER_SIZE,BUFFER_SIZE,NULL);if(NULL==EmptySemaphoreHandle){return2;}//创建Full信号量,表示缓冲池中满缓冲区数量。初始计数为0,最大计数为BUFFER_SIZE。FullSemaphoreHandle=CreateSemaphore(0,BUFFER_SIZE,NULL);if(NULL==FullSemaphoreHandle){return3;}//创建生产者线程。//ProducerHandle=CreateThread(0,//默认堆栈大小Producer,//线程函数入口地址NULL,//线程函数参数0,//创建标志NULL);//线程IDif(NULL==ProducerHandle){return4;}//创建消费者线程。ConsumerHandle=CreateThread(0,Consumer,NULL,0,NULL);if(NULL==ConsumerHandle){return5;}//等待生产者线程和消费者线程结束。WaitForSingleObject(ProducerHandle,INFINITE);WaitForSingleObject(ConsumerHandle,INFINITE);//关闭句柄CloseHandle(MutexHandle);8CloseHandle(EmptySemaphoreHandle);CloseHandle(FullSemaphoreHandle);CloseHandle(ProducerHandle);CloseHandle(ConsumerHandle);return0;}//生产者线程函数。ULONGProducer(PVOIDParam){inti;intInIndex=0;for(i=0;iPRODUCT_COUNT;i++){//WaitForSingleObject(EmptySemaphoreHandle,INFINITE);while(WAIT_TIMEOUT==WaitForSingleObject(EmptySemaphoreHandle,300)){printf(Producerwaitforemptysemaphoretimeout\n);}WaitForSingleObject(MutexHandle,INFINITE);printf(Producea%d\n,i);Buffer[InIndex]=i;InIndex=(InIndex+1)%BUFFER_SIZE;ReleaseMutex(MutexHandle);ReleaseSemaphore(FullSemaphoreHandle,1,NULL);//休息一会。每500毫秒生产一个数。Sleep(500);}return0;}//消费者线程函数。每次消耗一个/*ULONGConsumer(PVOIDParam){inti;intOutIndex=0;for(i=0;iPRODUCT_COUNT;i++){while(WAIT_TIMEOUT==WaitForSingleObject(FullSemaphoreHandle,300)){printf(Consumerwaitforfullsemaphoretimeout\n);}WaitForSingleObject(MutexHandle,INFINITE);printf(\t\t\tConsumea%d\n,Buffer[OutIndex]);OutIndex=(OutIndex+1)%BUFFER_SIZE;ReleaseMutex(MutexHandle);9ReleaseSemaphore(EmptySemaphoreHandle,1,NULL);//休息一会儿。让前10个数的消费速度比较慢,后面的较快。if(i10){Sleep(2000);}else{Sleep(100);}}return0;}*///消费者线程函数,每次消耗两个ULONGConsumer(PVOIDParam){inti;intOutIndex=0;for(i=0;iPRODUCT_COUNT;i+=2){while(WAIT_TIMEOUT==WaitForSingleObject(FullSemaphoreHandle,300)){printf(Consumerwaitfor
本文标题:操作系统实验第六讲进程的同步
链接地址:https://www.777doc.com/doc-2381245 .html