您好,欢迎访问三七文档
操作系统实验报告课程名称操作系统实验实验项目名称进程的同步学号班级姓名专业计算机学生所在学院计算机科学与技术学院指导教师实验室名称地点21#428哈尔滨工程大学计算机科学与技术学院1一、实验概述1.实验名称进程的同步2.实验目的a.使用EOS的信号量编程解决生产者—消费者问题,理解进程同步的义。b.调试跟踪EOS的信号量的工作过程,理解进程同步的原理。c.修改EOS的信号量算法,使之支持等待超时唤醒功能(有限等待),深理解进程同步的原理。3.实验类型验证型实验4.实验内容4.1.准备实验。4.2.使用EOS的信号量解决生产者-消费者问题。4.3.调试EOS信号量的工作过程4.3.1创建信号量4.3.2等待、释放信号量4.3.2.1等待信号量(不阻塞)4.3.2.2释放信号量(不唤醒)4.3.2.3等待信号量(阻塞)4.3.2.4释放信号量(唤醒)4.4.修改EOS的信号量算法二、实验环境OSLab集成实验环境。三、实验过程1.设计思路和流程图main函数流程图,Producer函数流程图和Consumer函数流程图2(a)main函数流程图;(b)Producer函数流程图;(c)Consumer函数流程图问题一:生产者在生产了13号产品后本来要继续生产14号产品,可此时生产者为什么必须等待消费者消费了4号产品后,才能生产14号产品呢?生产者和消费者是怎样使用同步对象来实现该同步过程的呢?答:临界资源的访问限制,程序中限定了缓冲池的大小为10,只有缓冲池有空余时生产者才能向里边放产品,同时只有缓冲池有产品时消费者才能向外取东西。当生产者生产了13号产品后,共生产了从0到13的14个产品,但是只消费了从0到3的4个产品,所以缓冲池中的10个缓冲区就都被占用了,所以不能继续生产14号产品,而要等到消费者消费掉一个产品后,缓冲池有空余位置,才能继续生产14号产品。当生产者线程生产了13号产品后,此时Full信号量的值为10,而Empty信号量的值为0,此时若生产者线程要再生产一个产品,先对Empty减1,此时Empty值小于零,生产者线程进入等待队列;而此时若有一个消费者线程要消费一个产品,先对Full减1,此时Full值为9,大于0,如果没有线程占用缓冲池,消费者可以消费一个产品。这样,生产者和消费者就能实现同步过程了。问题二:修改EOS的信号量算法(一次消费1个产品的,一次消费2个产品)3(1)、一次消费1个产品ULONGConsumer(PVOIDParam){inti;intOutIndex=0;for(i=0;iPRODUCT_COUNT;i++){WaitForSingleObject(FullSemaphoreHandle,INFINITE);WaitForSingleObject(MutexHandle,INFINITE);printf(\t\t\tConsumea%d\n,Buffer[OutIndex]);OutIndex=(OutIndex+1)%BUFFER_SIZE;ReleaseMutex(MutexHandle);ReleaseSemaphore(EmptySemaphoreHandle,1,NULL);////休息一会儿。让前10个数的消费速度比较慢,后面的较快。//if(i10){Sleep(2000);}else{Sleep(100);}}return0;}结果:4(2)、一次消费2个产品ULONGConsumer(PVOIDParam){inti;intOutIndex=0;for(i=0;iPRODUCT_COUNT;i+=2){while(WAIT_TIMEOUT==WaitForSingleObject(FullSemaphoreHandle,300)){printf(Consumerwaitforfullsemaphoretimeout\n);}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;printf(\t\t\tConsumea%d\n,Buffer[OutIndex]);OutIndex=(OutIndex+1)%BUFFER_SIZE;ReleaseMutex(MutexHandle);ReleaseSemaphore(EmptySemaphoreHandle,2,NULL);//5//休息一会儿。让前14个数的消费速度比较慢,后面的较快。//if(i14){Sleep(2000);}else{Sleep(100);}}return0;}运行结果:6问题三:绘制ps/semaphore.c文件内PsWaitForSemaphore和PsReleaseSemaphore函数的流程图。PsWaitForSemaphore流程图7PsReleaseSemaphore函数的流程图:84.主要数据结构、实现代码及其说明修改PsWaitForSemaphore函数:if(Semaphore-Count0)//如果信号量大于零,说明尚有资源,可以为线程分配Semaphore-Count--;else//否则,说明资源数量不够,不能再为线程分配资源,因此要使线程等待if(Semaphore-Count==0)s=PspWait(&Semaphore-WaitListHead,Milliseconds);修改PsReleaseSemaphore函数:if(ReleaseCount0)//ReleaseCount大于0才执行释放操作{Semaphore-Count++;while((!ListIsEmpty(&Semaphore-WaitListHead))&&(ReleaseCount)){PspWakeThread(&Semaphore-WaitListHead,STATUS_SUCCESS);//唤醒线程PspThreadSchedule();//线程调度ReleaseCount--;}//循环唤醒线程Semaphore-Count=Semaphore-Count+ReleaseCount;Status=STATUS_SUCCESS;}elseprintf(Error:ReleaseCountisnegative!);}//否侧输出ReleaseCount值错误修改Producer函数:WaitForSingleObject(EmptySemaphoreHandle,INFINITE);替换为while(WAIT_TIMEOUT==WaitForSingleObject(EmptySemaphoreHandle,300)){printf(Producerwaitforemptysemaphoretimeout\n);}//超时300ms则输出Producerwaitforemptysemaphoretimeout修改Consumer函数:WaitForSingleObject(FullSemaphoreHandle,INFINITE);替换为9while(WAIT_TIMEOUT==WaitForSingleObject(FullSemaphoreHandle,300)){printf(Consumerwaitforfullsemaphoretimeout\n);}//超时300ms则输出Consumerwaitforfullsemaphoretimeout5.源程序并附上注释#includepsp.hVOIDPsInitializeSemaphore(INPSEMAPHORESemaphore,INLONGInitialCount,INLONGMaximumCount)/*++功能描述:初始化信号量结构体。参数:Semaphore--要初始化的信号量结构体指针。InitialCount--信号量的初始值,不能小于0且不能大于MaximumCount。MaximumCount--信号量的最大值,必须大于0。返回值:无。--*/{ASSERT(InitialCount=0&&InitialCount=MaximumCount&&MaximumCount0);Semaphore-Count=InitialCount;Semaphore-MaximumCount=MaximumCount;ListInitializeHead(&Semaphore-WaitListHead);}STATUSPsWaitForSemaphore(10INPSEMAPHORESemaphore,INULONGMilliseconds)/*++功能描述:信号量的Wait操作(P操作)。参数:Semaphore--Wait操作的信号量对象。Milliseconds--等待超时上限,单位毫秒。返回值:STATUS_SUCCESS。当你修改信号量使之支持超时唤醒功能后,如果等待超时,应该返回STATUS_TIMEOUT。--*/{BOOLIntState;STATUSflag;ASSERT(KeGetIntNesting()==0);//中断环境下不能调用此函数。IntState=KeEnableInterrupts(FALSE);//开始原子操作,禁止中断。////目前仅实现了标准记录型信号量,不支持超时唤醒功能,所以PspWait函数//的第二个参数的值只能是INFINITE。//if(Semaphore-Count0){Semaphore-Count--;flag=STATUS_SUCCESS;//PspWait(&Semaphore-WaitListHead,INFINITE);}elseflag=PspWait(&Semaphore-WaitListHead,Milliseconds);11KeEnableInterrupts(IntState);//原子操作完成,恢复中断。returnflag;//KeEnableInterrupts(IntState);//原子操作完成,恢复中断。//returnSTATUS_SUCCESS;}STATUSPsReleaseSemaphore(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;12}else{////记录当前的信号量的值。//if(NULL!=PreviousCount){*PreviousCount=Semaphore-Count;}intmm=Semaphore-Count;////目前仅实现了标准记录型信号量,每执行一次信号量的释放操作//只能使信号量的值增加1。////Semaphore-Count
本文标题:进程的同步HEU
链接地址:https://www.777doc.com/doc-5526957 .html