




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
山东科技大学操作系统课程设计报告题目:并发控制-生产者-消费者问题姓名:安文龙学号:200901051301班级:计算机09-2班指导老师:房胜学院:信息科学与工程学院目录一:设计要求二:背景知识三:设计环境四:设计思路五:程序结构六:关键代码分析:七:运行结果及分析:八:Q&A九:参考源代码一:设计要求:完成N个生产者和M个消费者之间的并发控制,N、M不低于5,缓冲区大小不小于5个,生成的消息为一个自定义的数据结构。某个生产者进程生产的消息供K个消费者进程消费。K<=M。某些消费进程消费多个生产者生产的消息。每个生产进程生产M个消息后结束运行。如果一个消费者进程没有对应的生产者进程在运行后,也结束运行。并发控制要求:生产者消费者之间正确的互斥和同步采用线程、进程两种方式完成测试文件。测试要求:不同的N和M,不同的K,以及线程和进程。运行结果显示要求:每个线程/进程的动态运行信息运行时间每个进程或线程是否都完成了任务设计目的: 通过在Windows2K/XP环境下对经典的生产者-消费者问题的编程实现,加深理解信号量和wait、signal操作的原理对Win32API中定义的IPC函数和涉及到的几种同步对象有更进一步的了解二、背景知识: 进程同步的主要任务是对多个相关进程在执行次序上进行协调,以使并发执行的诸进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性。当进程间要共享某种资源时,这种资源被放入临界区,多个进程通过互斥的访问临界区来实现对这种临界资源的共享。 利用信号量机制实现进程互斥。为了使多个进程互斥的访问临界资源,须为该资源设置一互斥信号量metex,然后将各进程访问资源的临界区置于wait(mutex)和siinal(mutex)操作之间即可。这样,每个欲访问该临界资源的进程在进入临界区之前,都要先对mutex执行wait操作,若该资源此刻为被访问,本次wait操作必然成功,进程就可以进入自己的临界区。当访问临界资源的进程退出临界区后,又应对mutex执行signal操作,以便释放该临界资源。从而保证了该临界资源能被互斥的访问。Critical_section:每个线程中访问临界资源的那段程序称为临界区(CriticalSection)(临界资源是一次仅允许一个线程使用的共享资源)。每次只准许一个线程进入临界区,进入后不允许其他线程进入。不论是硬件临界资源,还是软件临界资源,多个线程必须互斥地对它进行访问。临界区在使用时以CRITICAL_SECTION结构对象保护共享资源,并分别用EnterCriticalSection()和LeaveCriticalSection()函数去标识和释放一个临界区。所用到的CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。Mutex:互斥(体)又称同步基元使用了System.Threading命名空间。当创建一个应用程序时,将同时创建一个系统范围内的命名的Mutex对象。这个互斥元在整个操作系统中都是可见的。当已经存在一个同名的互斥元时,构造函数将会输出一个布尔值。程序代码通过检测这个布尔值来判断指定的程序实例是否启动,如果已经存在同名互斥元的话,则显示一个对话框,告知用户应用程序已经启动,并退出应用程序。Createthread():a)概述:当使用CreateProcess调用时,系统将创建一个进程和一个主线程。CreateThread将在主线程的基础上创建一个新线程b)格式:HANDLECreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes,DWORDdwStackSize,LPTHREAD_START_ROUTINElpStartAddress,LPVOIDlpParamiter,DWORDdwCreationFlags,LpdwordlpThread);c)参数及说明(1)lpThreadAttributes:指向一个LPSECURITY_ATTRIBUTES。(2)dwStackSize:定义原始堆栈的大小。(3)lpStartAddress:指向使用LPTHRAED_START_ROUTINE类型定义的函数。(5)lpParamiter:定义一个给进程传递参数的指针。(6)dwCreationFlags:定义控制线程创建的附加标志。(7)lpThread:保存线程标志符(32位)Createsemaphore():a)概述:创建一个信号量对象b)格式HANDLECreateSemaphore(LPSECURITY_ATTRIBUTESlpSemaphoreAttributes,LONGlInitialCount,LONGlMaximumCount,LPCTSTRlpName);c)参数及说明:(1)lpSemaphoreAttributes::定义了信号机的安全特性,指向SECURITY_ATTRIBUTES结构,若为NULL则表示使用默认属性(2)lInitialCount:设置信号量的初始计数。可设置零到lMaximumCount之间的一个值。(3)lMaximumCount:设置信号量的最大计数。(4)lpName:信号量对象的名称。Waitformultipleobjects():a)概述:Windows中的一个功能非常强大的函数,几乎可以等待Windows中的所有的内核对象(关于该函数的描述和例子见MSDN,)。但同时该函数在用法上却需要一定的技巧b)格式:DWORDWaitForMultipleObjects(DWORDnCount,constHANDLE*lpHandles,BOOLbWaitAll,DWORDdwMilliseconds);c)参数及说明:(1)nCount:等待的线程数目(2)lpHandles:等待的线程句柄数组(3)bWaitAll:是否等待全部信号量有效再向下执行(4)dwMilliseconds:等待时间Waitforsingleobject():a)概述:使程序处于等待状态,直到信号量hHandle出现(即其值大于等于1)或超过规定的等待时间b)格式:DWORDWaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds);C)参数及说明:(1)hHandle:信号量指针,可以指定一系列的对象。(2)dwMilliseconds:等待的最长时间(INFINITE为无限等待)Releasesemaphore():a)概述:对指定信号量加上一个指定大小的量。成功执行则返回非0值b)格式:BOOLReleaseSemaphore(HANDLEhSemaphore,LONGlReleaseCount,LPLONGlppreviousCount);c参数及说明:(1)hSemaphore:信号量指针。(2)lReleaseCount:信号量的增量。(3)lppreviousCount:保存信号量当前值。三、设计环境:MicrosoftVisualC++6.0四、设计思路: 缓冲区为临界资源,当有无论生产者线程还是消费者线程访问某一缓冲区时,其他任何线程都不能访问该缓冲区。只要缓冲区没有被占满生产者就可以生产产品放入空闲缓冲区,否则生产者要等待消费者消费产品将缓冲区释放。只要缓冲区不空消费者就可以消费其中的产品,否则消费者要等待生产者生产产品放入缓冲区。 在程序中已经定义了生产者跟消费者的数目。当生产者线程被触发时,生产者通过判断哪个缓冲区空闲,第几个产品还没有被生产,将产品生产并放入空闲缓冲区并将产品信息赋值给其对应的产品信息结构体,与此同时将缓冲区标志为非空。当消费者线程被触发时,寻找非空缓冲区并判断该产品是否属于其消费,若属于则消费产品并释放信号量。直到生产者生产完M个产品,消费者消费完对应的产品,线程结束与运行,被关闭。五、程序结构:创建消费者者线程创建生产者线程创建消费者者线程创建生产者线程等待信号量full等待信号量等待信号量full等待信号量empty消费者消费生产者生产产品消费者消费生产者生产产品释放信号量释放信号量empty释放信号量释放信号量full六、关键代码分析:定义产品信息结构体//自定义结构体:产品信息structProInfo{ intpID;//Producer intProductID;//product intcID;//Theconsumer intbuf_station;//Inthebufferlocation};生产者线程函数中,生产者通过等待信号量以及寻找空闲缓冲区将生产的产品放在合适的空闲缓冲区while(true){ for(i=0;i<buf_size;i++){ WaitForSingleObject(empty,-1); WaitForSingleObject(mutex,-1); Sleep(50); if(BUFFER[i]==0){ for(j=1;j<=ConsumorNum;j++){ if(productor[id][j]==0){ productor[id][j]=1; BUFFER[i]=1; cout<<"producer"<<id<<"producetheproductof"<<j<<endl; P_Info[i].pID=id; P_Info[i].ProductID=j; P_Info[i].buf_station=i; if((i+1)%ConsumorNum!=0) P_Info[i].cID=(i+1)%ConsumorNum; else P_Info[i].cID=(i+2)%ConsumorNum; break; } } } ReleaseSemaphore(mutex,1,NULL); ReleaseSemaphore(full,1,NULL); } }消费者线程通过等待full信号量,并寻找属于其消费的产品进行消费while(true){ for(i=0;i<buf_size;i++){ WaitForSingleObject(full,-1); WaitForSingleObject(mutex,-1); Sleep(50); if(P_Info[i].cID==id){ cout<<"consumer"<<id<<"consumetheproducer"<<P_Info[i].pID<<"oftheproduct"<<P_Info[i].ProductID<<endl; BUFFER[i]=0; P_Info[i].cID=0; } ReleaseSemaphore(mutex,1,NULL); ReleaseSemaphore(empty,1,NULL); } }七、运行结果及分析:运行结果:结果分析: 生产者生产产品与消费者消费产品是随机进行的,只要缓冲区不满生产者就可以生产产品,只要缓冲区不空消费者就可以消费属于它消费的产品。总结体会:在编写程序之前最好是先有个成熟的程序架构,因为开始我没有仔细去思考应该怎么去编写才能更好的实现老师的作业要求,而是凭着上课时对老师讲课的理解就开始了程序的编写,结果写着写着就没有的思路,不知道下一步该干什么,经过这一教训后,我开始了对程序的总体设计,参详相关资料,也到网上去研究相关课题的程序,经过几天的努力,终于做出了程序的雏形,但开始时的结果并不满足老师题目的要求,运行的结果并不是随机的,接下来我就开始解决这个问题,最后做出了现在的程序。编程需要思考,更需要思想我觉得,所以,以后我会加强这方面的练习。八:Q&AQ:了解Win32API中定义的IPC函数,说明比较说明涉及到的几种同步对象。你猜测哪一种操作速度比较快,证实你的想法,并给出一个合理的解释A:互斥量,临界区,事件,信号量。临界区更快。因为临界区效率比较高,它不需要切换到内核执行。九:参考源代码#include<windows.h>#include<iostream>usingnamespacestd;//Defineconstant#definebuf_size6 //Numberofbuffers#define M50 //Customstructure--productinformationstructProInfo{ intpID;//Producer intProductID;//product intcID;//Theconsumer intbuf_station;//Inthebufferlocation};//GlobalvariablesintProductorNum=5; //thenumberofProducerint ConsumorNum=5; //thenumberofconsumerintBUFFER[buf_size];//Thebufferisproductof0saidno,1expressedintproductor[M][M]; //Iftheproducerofiproducttheproductionofj,product[i][j]=1ProInfoP_Info[buf_size]; //StoragearrayHANDLE empty; //BufferemptysemaphoreHANDLE full; //BufferfullsemaphoreHANDLEmutex; //Mutex//FunctiondeclarationDWORDWINAPIThreadProducer(LPVOID);DWORDWINAPIThreadConsumer(LPVOID);intmain(){ cout<<"ProductorNum=5ConsumorNum=5"<<"\n"; cout<<"nowproducerproducetheproductandconsumerconsumetheproduct"<<"\n"<<"----------------------------------------------"<<"\n"; inti,j; intp_id[M],c_id[M];//storeProducers',consumers'number,whenthreadsarecreated,passtoathreadfunctionparameters HANDLEpThread[M]; HANDLEcThread[M]; //Createsemaphore empty=CreateSemaphore(NULL,buf_size,buf_size,NULL); full=CreateSemaphore(NULL,0,buf_size,NULL); mutex=CreateSemaphore(NULL,1,1,NULL); //Createproducerthread for(i=0;i<ProductorNum;i++){ p_id[i]=i+1; pThread[i]=CreateThread(NULL,0,ThreadProducer,p_id+i,0,NULL); } //Createconsumorthread for(j=0;j<ConsumorNum;j++){ c_id[j]=j+1; cThread[j]=CreateThread(NULL,0,ThreadConsumer,c_id+j,0,NULL); } //Waitforallthreadstoterminate WaitForMultipleObjects(ProductorNum,pThread,TRUE,INFINITE); WaitForMultipleObjects(ConsumorNum,cThread,TRUE,INFINITE);return0;}//producerthreadDWORDWINAPIThreadProducer(LPVOIDlpParam){ intid=*(int*)lpParam; inti,j; while(true){ for(i=0;i<buf_size;i++){ WaitForSingleObject(empty,-1); WaitForSingleObject(mutex,-1); Sleep(50); if(BUFFER[i]==0){ for(j=1;j<=ConsumorNum;j++){ if(productor[id][j]==0){ productor[id][j]=1; BUFFER[i]=1; cout<<"producer"<<id<<"prod
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2031年中国小麦蛋白市场供需格局及投资规划研究报告
- 2025-2031年中国学校信息化行业市场深度分析及投资策略研究报告
- 2025-2031年中国即饮茶行业市场运行态势与投资战略咨询报告
- 小升初语文总复习-专题九 现代文阅读·说明议论
- 2025-2031年中国上海数字经济行业发展监测及投资战略咨询报告
- 2025-2031年中国AI治理行业市场调查研究及发展趋势预测报告
- 信息技术项目安全风险防范措施
- 2025-2030年高亮度PAR灯项目商业计划书
- 2025-2030年阀门总装流水线项目投资价值分析报告
- 2025年化合物半导体的外延生长设备项目投资风险评估报告
- JT-T 1495-2024 公路水运危险性较大工程专项施工方案编制审查规程
- 2024年卫生资格(中初级)-初级药师笔试考试历年真题含答案
- T∕CACM 1078-2018 中医治未病技术操作规范 拔罐
- DB11∕T 722-2022 节水灌溉工程自动控制系统设计规范
- 《传染病》PPT课件完美版-2024鲜版
- 2024山东春季高考春招单招日语模拟练习及答案详解
- 社会主义现代化建设的教育科技人才战略
- 《舞台布景设计》课件
- 篮球突分技术与配合-教学设计
- 林业面试题目及答案
- 老顾客带新顾客方案
评论
0/150
提交评论