学习中心:专业:年级:年春/秋季学号:学生:题目:进程同步与互斥生产者-消费者问题1.谈谈你对本课程学习过程中的心得体会与建议?转眼间,学习了一个学期的计算机操作系统课程即将结束。在这个学期中,通过老师的悉心教导,让我深切地体会到了计算机操作系统的一些原理和具体操作过程。在学习操作系统之前,我只是很肤浅地认为操作系统只是单纯地讲一些关于计算机方面的操作应用,并不了解其中的具体操作过程和实用性。通过这一学期的学习,我才知道操作系统(OperatingSystem,简称OS)是管理计算机系统的全部硬件资源包括软件资源及数据资源;控制程序运行;改善人机界面;为其它应用软件提供支持等,使计算机系统所有资源最大限度地发挥作用,为用户提供方便的、有效的、友善的服务界面。操作系统这门课程并不是教你如何使用操作系统的,而是讲操作。总而言之,操作系统的一些原理在生活中都可以找到相应的例子。结合生活中的例子,可以化抽象为具体,我们会更加清楚地了解到其原理与操作过程。我觉得通过我们的不断学习,结合生活中的实际问题,我们就会把操作系统学得更好。总体来说,通过这次的对操作系统的总结,有收获也有遗憾、不足的地方,但我想,我已经迈入了操作系统的大门,只要我再认真努力的去学习,去提高,肯定能让自己的知识能力更上一层楼.1设计思路及主要代码分析1.1设计思路在这次设计中定义的多个缓冲区不是环形循环的,并且不需要按序访问。其中生产者可以把产品放到某一个空缓冲区中,消费者只能消费被指定生产者生产的产品。本设计在测试用例文件中指定了所有生产和消费的需求,并规定当共享缓冲区的数据满足了所有有关它的消费需求后,此共享才可以作为空闲空间允许新的生产者使用。本设计在为生产者分配缓冲区时各生产者之间必须互斥,此后各个生产者的具体生产活动可以并发。而消费者之间只有在对同一个产品进行消费时才需要互斥,它们在消费过程结束时需要判断该消费者对象是否已经消费完毕并释放缓冲区的空间。1.2程序流程图主函数初始化缓冲区,消费请求队列及部分同步对象提取线程信息完成线程相关同步对象的初始化等待所有线程结束创建线程模拟生产和消费程序结束消费者有消费请求?此请求可满足?确定产品位置此产品正被消费?进入临界区(对同一产品进行请求的消费者之间互斥)消费产品、并判断是否应该释放产品所占缓冲区结束消费进程生产者存在空缓冲区?另一生产者正在生产?进入临界区(所有生产者之间互斥)从空缓冲区中为本生产者的产品分配一个空间退出临界区在该缓冲区放入产品通过信号量通知等待本产品的消费者结束生产进程退出临界区YYYNNNNYYN1.3基本内容在设计程序时主要有三个主体部分、三个辅助函数和一个数据结构。其中主体部分为一个主函数main(),用于初始化缓冲区和各个同步对象,并完成线程信息的读入,最后根据该组的线程记录启动模拟线程,并等待所有线程的运行结束后退出程序;生产者函数Produce()和消费者函数Consume(),生产者和消费者函数运行于线程中完成对缓冲区的读、写动作,根据此处生产消费的模型的特点,生产者和消费者之间通过使用同步对象实现了生产和消费的同步与互斥,是本实验的核心所在。另外三个辅助性函数被生产者和消费者函数调用,是上述生产和消费函数中对缓冲区进行的一系列处理。定义一个数据结构,记录在测试文件中指定的每一个线程的参数。1)用一个整型数组Buffer_Critical来代表缓冲区。不管是生产产品还是对已有的产品的消费都需要访问该组缓冲区。2)进程信息ThreadInfo数据结构,包含线程的各个信息。structThreadInfo{intserial;//线程序列号charentity;//是P还是Cdoubledelay;//线程延迟intthread_request[MAX_THREAD_NUM];//线程请求队列intn_request;//请求个数};3)在实现本程序的消费生产模型时,具体的通过如下同步对象实现互斥:①设一个互斥量h_mutex,以实现生产者在查询和保留缓冲区内的下一个位置时进行互斥。②每一个生产者用一个信号量与其消费者同步,通过设置h_Semaphore[MAX_THREAD_NUM]信号量③数组实现,该组信号量用于相应的产品已产生。同时用一个表示空缓冲区数目的信号量empty_semaphore进行类似的同步,只是缓冲区中是否存在空位置,以便开始生产下一个产品。④每一个缓冲区用一个同步对象实现该缓冲区上消费者之间的互斥,这通过设置临界区对象数组PC_Crilical[MAX_BUFFER_NUM]实现。1.4程序代码#includestdafx.h#includewindows.h#includefstream.h#includestdio.h#includestring#includeconio.h#defineMAX_BUFFER_NUM10#defineINTE_PER_SEC1000#defineMAX_THREAD_NUM64//定义一个结构,记录在测试文件中指定的每一个线程的参数structThreadInfo{//进程信息ThreadInfo数据结构,包含线程的各个信息intserial;//线程序列号charentity;//是P还是Cintdelay;//线程延迟intthread_request[MAX_THREAD_NUM];//线程请求队列intn_request;//请求个数};//每一个缓冲区用一个同步对象实现该缓冲区上消费者之间的互斥,这通过设置临界区对象数组PC_Crilical[MAX_BUFFER_NUM]实现。CRITICAL_SECTIONPC_Critical[MAX_BUFFER_NUM];//用一个整型数组Buffer_Critical来代表缓冲区。不管是生产产品还是对已有的产品的消费都需要访问该组缓冲区。intBuffer_Critical[MAX_BUFFER_NUM];HANDLEh_Thread[MAX_THREAD_NUM];ThreadInfoThread_Info[MAX_THREAD_NUM];//设一个互斥量h_mutex,以实现生产者在查询和保留缓冲区内的下一个位置时进行互斥。HANDLEh_mutex;//每一个生产者用一个信号量与其消费者同步,通过设置h_Semaphore[MAX_THREAD_NUM]信号量数组实现,该组信号量用于相应的产品已产生。HANDLEh_Semaphore[MAX_THREAD_NUM];//同时用一个表示空缓冲区数目的信号量empty_semaphore进行类似的同步,只是缓冲区中是否存在空位置,以便开始生产下一个产品。HANDLEempty_semaphore;DWORDn_Thread=0;DWORDn_Buffer_or_Critical;voidProduce(void*p);voidConsume(void*p);boolIfInOtherRuquest(int);intFindProducePosition();intFindBufferPosition(int);//函数输入数据,提取线程信息到数据结构中,初始化临界区,创建信号量,创建线程intmain(void){//声明所需变量DWORDwait_for_all;ifstreaminFile;//初始化缓冲区for(inti=0;iMAX_BUFFER_NUM;i++)Buffer_Critical[i]=-1;//初始化每个线程的请求序列for(intj=0;jMAX_THREAD_NUM;j++){for(intk=0;kMAX_THREAD_NUM;k++)Thread_Info[j].thread_request[k]=-1;Thread_Info[j].n_request=0;}//初始化临界段对象for(i=0;iMAX_BUFFER_NUM;i++)InitializeCriticalSection(&PC_Critical[i]);//打开输入文件,按照规定的格式提取线程等信息inFile.open(test.txt);//从文件中获取实际的缓冲区的数目inFilen_Buffer_or_Critical;inFile.get();printf(输入文件是:\n);//显示获得的缓冲区数目信息printf(%d个缓冲区\n,(int)n_Buffer_or_Critical);//提取每个线程信息到相应的数据结构中while(inFile){inFileThread_Info[n_Thread].serial;inFileThread_Info[n_Thread].entity;inFileThread_Info[n_Thread].delay;charc;inFile.get(c);while(c!='\n'&&!inFile.eof()){inFileThread_Info[n_Thread].thread_request[Thread_Info[n_Thread].n_request++];inFile.get(c);}n_Thread++;}//显示获得的线程信息,便于确认正确性for(j=0;j(int)n_Thread;j++){intTemp_serial=Thread_Info[j].serial;charTemp_entity=Thread_Info[j].entity;intTemp_delay=Thread_Info[j].delay;printf(线程%2d%c%d,Temp_serial,Temp_entity,Temp_delay);intTemp_request=Thread_Info[j].n_request;for(intk=0;kTemp_request;k++)printf(%d,Thread_Info[j].thread_request[k]);coutendl;}cout------------------------------------------------------endl;empty_semaphore=CreateSemaphore(NULL,n_Buffer_or_Critical,n_Buffer_or_Critical,semaphore_for_empty);//创建在模拟过程中的几个信号量h_mutex=CreateMutex(NULL,FALSE,mutex_for_update);//用线程的ID号来为相应的生产线程的产品读写时所使用的同步信号量命名for(j=0;j(int)n_Thread;j++){std::stringlp=semaphore_for_produce_;inttemp=j;while(temp){//转换为字符charc=(char)(temp%10);lp+=c;temp/=10;}h_Semaphore[j+1]=CreateSemaphore(NULL,0,n_Thread,lp.c_str());}//生产者消费者线程for(i=0;i(int)n_Thread;i++){if(Thread_Info[i].entity=='P')h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(Thread_Info[i]),0,NULL);elseh_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),&(Thread_Info[i]),0,NULL);}//主线程等待各个线程结束wait_for_all=WaitForMultipleObjects(n_Thread,h_Thread,TRUE,-1);cout--------------------