进程同步机制与互斥-生产者消费者问题_第1页
进程同步机制与互斥-生产者消费者问题_第2页
进程同步机制与互斥-生产者消费者问题_第3页
进程同步机制与互斥-生产者消费者问题_第4页
进程同步机制与互斥-生产者消费者问题_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、进程同步机制与互斥生产者消 费者问题学习中心:专 业:年 级: 年 春/秋季学 号:学 生:题 目:进程同步与互斥 生产者-消费者问题1.谈谈你对本课程学习过程中的心得体会与建议?转眼间、学习了一个学期的计算机操作系统课程即将结束。在这个学期中、 通过老师的悉心教导,让我深切地体会到了计算机操作系统的一些原理和具体 操作过程。在学习操作系统之前,我只是很肤浅地认为操作系统只是单纯地讲 一些关于计算机方面的操作应用,并不了解其中的具体操作过程和实用性。通 过这一学期的学习,我才知道操作系统(Operating System ,简称 OS)是管理计算 机系统的全部硬件资源包括软件资源及数据资源;控

2、制程序运行;改善人机界 面;为其它应用软件提供支持等,使计算机系统所有资源最大限度地发挥作用, 为用户提供方便的、有效的、友善的服务界面。操作系统这门课程并不是教你 如何使用操作系统的,而是讲操作。总而言之,操作系统的一些原理在生活中 都可以找到相应的例子。结合生活中的例子、可以化抽象为具体、我们会更加 清楚地了解到其原理与操作过程。我觉得通过我们的不断学习,结合生活中的 实际问题、我们就会把操作系统学得更好。总体来说、通过这次的对操作系统 的总结,有收获也有遗憾、不足的地方,但我想,我已经迈入了操作系统的大 门.只要我再认真努力的去学习.去提高.肯定能让自己的知识能力更上一层 楼.第2页/共

3、25页设计思路及主要代码分析设计思路在这次设计中定义的多个缓冲区不是环形循环的,并且不需要按序访问。其中生产者可以把产品放到某一个空缓冲区中,消费者只能消费被指定生产者生产的产品。本设计在测试用例文件中指定了所有 生产和消费的需求,并规定当共享缓冲区的数据满足了所有有关它的 消费需求后,此共享才可以作为空闲空间允许新的生产者使用。本设计在为生产者分配缓冲区时各生产者之间必须互斥,此后各 个生产者的具体生产活动可以并发。而消费者之间只有在对同一个产第3页/共25页品进行消费时才需要互斥,它们在消费过程结束时需要判断该消费者 对象是否已经消费完毕并释放缓冲区的空间程序流程图确定产品位置进入临界区(

4、对同一产品进 行请求的消费者之间互斥)消费产品、并判断是否应该 释放产品所占缓冲区退出临界区进入临界区(所有生产者之间互斥)从空缓冲区中为本生产者 的产品分配一个空间退出悔界区. 4r在该缓冲区放入产品通过信号量通知等待本产 品的消费者确定产品位置进入临界区(对同一产品进 行请求的消费者之间互斥)消费产品、并判断是否应该 释放产品所占缓冲区退出临界区进入临界区(所有生产者之间互斥)从空缓冲区中为本生产者 的产品分配一个空间退出悔界区. 4r在该缓冲区放入产品通过信号量通知等待本产 品的消费者第4页/共25页基本内容在设计程序时主要有三个主体部分、三个辅助函数和一个数据结 构。其中主体部分为一个

5、主函数main (),用于初始化缓冲区和各个 同步对象,并完成线程信息的读入,最后根据该组的线程记录启动模 拟线程,并等待所有线程的运行结束后退出程序;生产者函数Produce ()和消费者函数Consume。,生产者和消 费者函数运行于线程中完成对缓冲区的读、写动作,根据此处生产消费的模型的特点,生产者和消费者之间通过使用同步对象实现了生产 和消费的同步与互斥,是本实验的核心所在。另外三个辅助性函数被生产者和消费者函数调用,是上述生产和 消费函数中对缓冲区进行的一系列处理。定义一个数据结构,记录在测试文件中指定的每一个线程的参 数。用一个整型数组 Buffer_Critical来代表缓冲区。

6、不管是生产产品还是对已有的产品的消费都需要访问 该组缓冲区。进程信息ThreadInfo数据结构,包含线程的各个信息第5页/共25页struct Threadinfo ();3)在实现本程序的消费生产模型时,具体的通过如 下同步对象实现互斥:设一个互斥量h_mutex,以实现生产者在查询和保留缓冲 区内的下一个位置时进行互斥。每一个生产者用一个信号量与其消费者同步,通过设置h_SemaphoreMAX_THREAD_NUM量数组实现,该组信号量用于相应的产品已产生。同时用一第6页/共25页 个表示空缓冲区数目的信号量 empty_semaphore进行类似的同步,只是缓冲区中是否存在空位置,以

7、便开始生产下一个产品。每一个缓冲区用一个同步对象实现该缓冲区上消费者之间的互斥,这通过设置临界区对象数组 PC_CrilicalMAX_BUFFER_NUM 实现。1.4程序代码#include#include#include#include#include#includedefine MAX_BUFFER_NUM10define INTE_PER_SEC 1000define MAX_THREAD_NUM64/定义一个结构,记录在测试文件中指定的 每一个线程的参数struct ThreadInfo第7页/共25页/进程信息Threadinfo 数据结构,包含线 程的各个信息intserial

8、;/线程序列号charentity;是P还是Cintdelay;/线程延迟intthread_requestMAX_THREAD_NUM;/线程请求队列intn_request;/请求个数);/每一个缓冲区用一个同步对象实现该缓冲 区上消费者之间的互斥,这通过设置临界区对 象数组 PC_CrilicalMAX_BUFFER_NUM 实现。CRITICAL_SECTIONPC_CriticalMAX_BUFFER_NUM;/用一个整型数组Buffer_Critical来代表缓冲区。不管是生产产品还是对已有的产品的消第8页/共25页费都需要访问该组缓冲区。int Buffer_CriticalMA

9、X_BUFFER_NUM; HANDLEh_ThreadMAX_THREAD_NUM; ThreadInfoThread_InfoMAX_THREAD_NUM;/设一个互斥量h_mutex ,以实现生产者在 查询和保留缓冲区内的下一个位置时进行互 斥。HANDLE h_mutex;/每一个生产者用一个信号量与其消费者同 步, 通 过 设 置 h_SemaphoreMAX_THREAD_NUM 信 号 量数组实现,该组信号量用于相应的产品已产 生。HANDLEh_SemaphoreMAX_THREAD_NUM;/同时用一个表示空缓冲区数目的信号量 empty_semaphore 进行类似的同步,

10、只是缓 冲区中是否存在空位置,以便开始生产下一个 产品。HANDLE empty_semaphore;第9页/共25页DWORD n_Thread=0;DWORD n_Buffer_or_Critical;void Produce(void *p);void Consume(void *p);bool IfInOtherRuquest(int);int FindProducePosition();int FindBufferPosition(int);/函数 输入数据,提取线程信息到数据结构 中,初始化临界区,创建信号量,创建线程 int main(void)/声明所需变量DWORD wait

11、_for_all;ifstream inFile;/初始化缓冲区for(int i=0;iMAX_BUFFER_NUM;i+)Buffer_Criticali=-1;/初始化每个线程的请求序列for(int j=0;jMAX_THREAD_NUM;j+)第10页/共25页for(intk=0;kMAX_THREAD_NUM;k+)Thread_Infoj.thread_requestk=-1;Thread_Infoj.n_request=0;/初始化临界段对象for(i=0;in_Buffer_or_Critical;inFile.get();printf(输入文件是:n);/显示获得的缓冲区

12、数目信息printf( %d 个 缓 冲 区 n”,(int)n_Buffer_or_Critical);第11页/共25页/提取每个线程信息到相应的数据结构中while(inFile)(inFileThread_Infon_Thread.serial;inFileThread_Infon_Thread.entity;inFileThread_Infon_Thread.delay;char c;inFile.get(c);while(c!=n& !inFile.eof() (inFileThread_Infon_Thread.thread _requestThread_Infon_Thread

13、.n_requ est+;inFile.get(c);n_Thread+;/显示获得的线程信息,便于确认正确性第12页/共25页for(j=0;j(int)n_Thread;j+)(intTemp_serial=Thread_Infoj.serial;charTemp_entity=Thread_Infoj.entity;intTemp_delay=Thread_Infoj.delay;printf( 线程 %2d %c %d , Temp_serial,Temp_entity,Temp_delay);intTemp_request=Thread_Infoj.n_request;for(int

14、 k=0;kTemp_request;k+)printf(%d,Thread_Infoj.thread_requestk);coutendl;coutendl;empty_semaphore=CreateSemaphore( NULL,n_Buffer_or_Critical,n_Buffer_or_ Critical,semaphore_for_empty);第13页/共25页/创建在模拟过程中的几个信号量h_mutex=CreateMutex(NULL,FALSE, mutex_for_update);/用线程的ID号来为相应的生产线程的产 品读写时所使用的同步信号量命名for(j=0;j

15、(int)n_Thread;j+)std:stringlp=semaphore_for_produce_;int temp=j;while(temp)/转换为字符char c=(char)(temp%10);lp+=c;temp/=10;h_Semaphorej+1=CreateSemaphore(NULL,0,n_Thread,lp.c_str();/生产者消费者线程第14页/共25页for(i=0;i(int)n_Thread;i+)(if(Thread_Infoi.entity=P)h_Threadi=CreateThread(NULL,0,(LP THREAD_START_ROUTIN

16、E)(Produce),&( Thread_Infoi),0,NULL);elseh_Threadi=CreateThread(NULL,0,(LP THREAD_START_ROUTINE)(Consume), &(Thread_Infoi),0,NULL);/主线程等待各个线程结束wait_for_all=WaitForMultipleObjects( n_Thread,h_Thread,TRUE,-1);coutendl;printf(所有的生产者和消费者已经完成了 他们的工作。n);printf(请按任意键退出!n);_getch();第15页/共25页return 0;)/确认是否还

17、有对同一产品的消费请求未执 行bool IfInOtherRequest(int req)(for(int i=0;in_Thread;i+)for(intj=0;jThread_Infoi.n_request;j+)if(Thread_Infoi.thread_requestj=req)return TRUE;return FALSE;)/找出当前可以进行产品生产的空缓冲区位置;int FindProducePosition()(/用下面这个特殊值表示本缓冲区正处于 被写状态;int EmptyPosition;第16页/共25页for(int i=1;i=n_Buffer_or_Criti

18、cal;i+) if(Buffer_Criticali=-1) (EmptyPosition=i;Buffer_Criticali=-2;break;return EmptyPosition;int FindBufferPosition(int ProPos)(int TempPos;for(int i=1;iserial;m_delay=(DWORD)(ThreadInfo*)(p)-delay*INTE_PER_SEC);Sleep(m_delay);/开始请求生产printf( 生产者 %2d 请求生产 n,m_serial);/确认有缓冲区可以生产,同时将空位置 数empty减1;用于

19、生产者和消费者之间的 同步;wait_for_semaphore=WaitForSingleObject(empty_semaphore,-1);/互斥访问下一个可用于生产的空临界区,实现写写互斥wait_for_mutex=WaitForSingleObject( h_mutex,-1);第18页/共25页intProducePos=FindProducePosition();ReleaseMutex(h_mutex);/生产者在获得自己的空位置并做上标记后,以下写操作在生产者之间可以并发/在核心生产步骤中,程序将生产者的ID 作为产品编号放入,方便消费者识别printf(生产者 2d 开始

20、生产在位 置 2dn,m_serial,ProducePos);Buffer_CriticalProducePos=m_serial;printf( 生产者 %2d 完成生产 n,m_serial);printf( 位 置%2d:%3d 的产品 n,ProducePos,Buffer_Critical ProducePos);/使生产者写的缓冲区可以被多个消费者 使用,实现读写同步ReleaseSemaphore(h_Semaphorem_s erial,n_Thread,NULL);/消费者进程void Consume(void*p)第19页/共25页(DWORDwait_for_semap

21、hore,m_delay;/消费者的序列号和请求的数目int m_serial,m_requestNum;/本消费线程的请求队列intm_thread_requestMAX_THREAD_NUM ;/提取本线程信息到本地m_serial=(ThreadInfo*)(p)-serial;m_delay=(DWORD)(ThreadInfo*)(p)-delay*INTE_PER_SEC);m_requestNum=(ThreadInfo*)(p)-n_ request;for(int i=0;ithread_requesti;Sleep(m_delay);for(i=0;ithread_requ

22、esti=- 1;if(!IfInOtherRequest(m_thread_reques ti)/标记缓冲区为空Buffer_CriticalBufferPos=0;printf(消费者 %2d 消费完成 %2d n,m_serial,m_thread_requesti);printf(位置%2d:%3dn,BufferPos,Buffer_Critical BufferPos);第22页/共25页/离开临界区ReleaseSemaphore(empty_semaphore ,1,NULL);)else(printf( 消费者 %2d 消费完产 品%2dn,m_serial,m_thread_requesti); )LeaveCriticalSection(&PC_CriticalBuf ferPos);)2实验结果及问题分析2.1测试结果测试文件内容为:5第23页/共25页

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论