多个生产者—消费者问题

上传人:飞*** 文档编号:51391695 上传时间:2018-08-13 格式:PDF 页数:19 大小:535.63KB
返回 下载 相关 举报
多个生产者—消费者问题_第1页
第1页 / 共19页
多个生产者—消费者问题_第2页
第2页 / 共19页
多个生产者—消费者问题_第3页
第3页 / 共19页
多个生产者—消费者问题_第4页
第4页 / 共19页
多个生产者—消费者问题_第5页
第5页 / 共19页
点击查看更多>>
资源描述

《多个生产者—消费者问题》由会员分享,可在线阅读,更多相关《多个生产者—消费者问题(19页珍藏版)》请在金锄头文库上搜索。

1、操作系统实验报告多个生产者消费者问题姓名:学号:完成时间:一、 算法思想在这次实验中定义的多个缓冲区不是环形循环的,并且不需要按序访问。其中生产者可以把产品放到某一个空缓冲区中,消费者只能消费被指定生产者生产的产品。 我们在测试用例文件中指定了所有生产和消费的需求, 并规定当共享缓冲区的数据满足了所有有关它的消费需求后, 此共享才可以作为空闲空间允许新的生产者使用。本实验在为生产者分配缓冲区时各生产者之间必须互斥,此后各个生产者的具体生产活动可以并发。 而消费者之间只有在对同一个产品进行消费时才需要互斥, 它们在消费过程结束时需要判断该消费者对象是否已经消费完毕并释放缓冲区的空间。在设计程序时

2、分三个主体部分和三个辅助函数部分。其中主体部分为一个主函数main() ,用于初始化缓冲区和各个同步对象,并完成线程信息的读入, 最后根据该组的线程记录启动模拟线程,并等待所有线程的运行结束后退出程序;生产者函数void Produce ()和消费者函数 void Consume () ,生产者和消费者函数运行于线程中完成对缓冲区的读、写动作,根据此处生产消费的模型的特点,生产者和消费者之间通过使用同步对象实现了生产和消费的同步与互斥,是本实验的核心所在;另外三个辅助性函数被生产者和消费者函数调用,是上述生产和消费函数中对缓冲区进行的一系列处理。另附程序主体部分流程图如下:二、 P、V原语在本

3、程序中用到了三个同步对象。1、互斥量 Mutex 对象(核心对象同步)(1)CreateMutex: 创建有名或者无名的互斥对象函数原型:HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, 主函数初始化缓冲区,消费请求队列及部分同步对象提取线程信息完成线程相关同步对象的初始化等待所有线程结束创建线程模拟生产和消费程序结束消费者有消费请求?此请求可满足?确定产品位置此产品正被消费?进入临界区(对同一产品进行请求的消费者之间互斥)消费产品、并判断是否应该释放产品所占缓冲区结束消费进程生产者

4、存在空缓冲区?另一生产者正在写?进入临界区(所有生产者之间互斥)从空缓冲区中为本生产者的产品分配一个空间退出临界区在该缓冲区写入产品通过信号量通知等待本产品的消费者结束生产进程退出临界区Y Y Y N N N N Y Y N LPCTSTR lpName ); 参数说明:lpMutexAttributes:指定一个 SECURITY_ATTRIBUTES结构,或传递零值, 表示使用不允许继承的默认描述符bInitialOwner:如创建进程希望立即拥有互斥体,则设为TRUE 。一个互斥体同时只能由一个线程拥有lpName String :指定互斥体对象的名字。用vbNullString创建一个

5、未命名的互斥体对象。 如已经存在拥有这个名字的一个事件,则打开现有的已命名互斥体。这个名字可能不与现有的事件、信号机、可等待计时器或文件映射相符返回值:如果函数调用成功,返回互斥对象句柄;失败则返回NULL 程序中涉及语句: h_mutex=CreateMutex(NULL,FALSE,“mutex_for_update“); / 创建在模拟过程中的几个信号量(2) 【P操作】WaitForSingleObject: 当发生 (1) 指定对象处于信号态 (2) 超时 则该函数返回函数原型:DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMi

6、lliseconds ); 参数说明:hHandle:等待对象的句柄,dwMilliseconds :等待时间间隔,以毫秒为单位。返回值:WAIT_ABANDONED 0x00000080:当 hHandle 为 mutex时,如果拥有 mutex 的线程在结束时没有释放核心对象会引发此返回值。WAIT_OBJECT_0 0x00000000 :核心对象已被激活WAIT_TIMEOUT 0x00000102:等待超时WAIT_FAILED 0xFFFFFFFF :出现错误,可通过GetLastError得到错误代码 程序中涉及语句: / 互斥访问下一个可用于生产的空临界区,实现写写互斥 wai

7、t_for_mutex=WaitForSingleObject(h_mutex,-1); (3) 【V操作】 ReleaseMutex: 放弃指定互斥对象的所有权函数原型: BOOL ReleaseMutex (HANDLE hMutex ) ;参数说明:hMutex:要放弃的互斥对象的句柄。为CreateMutex 或 OpenMutex的返回值返回值:调用成功,返回值为非零值;失败返回0。若有回去更多的错误信息,可调用 GetLastError函数。 程序中涉及语句: ReleaseMutex(h_mutex); 2、临界段CriticalSection(非核心同步机制)(1)Initia

8、lizeCriticalSection: 初始化临界区对象函数原型: VOID InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); 参数说明: lpCriticalSection 临界资源对象指针返回值:无 程序中涉及语句: / 临界区对象的声明,用于管理缓冲区的互斥访问 CRITICAL_SECTION PC_Critical MAX_BUFFER_NUM; / 初始化临界区; for(i =0;i #include #include #include #include #define MAX_BUFFER_N

9、UM 10 #define INTE_PER_SEC 1000 #define MAX_THREAD_NUM 64 struct ThreadInfo int serial; char entity; int delay; int thread_requestMAX_THREAD_NUM; int n_request; ; CRITICAL_SECTION PC_Critical MAX_BUFFER_NUM; int Buffer_CriticalMAX_BUFFER_NUM; HANDLE h_ThreadMAX_THREAD_NUM; ThreadInfo Thread_InfoMAX_

10、THREAD_NUM; HANDLE empty_semaphore; HANDLE h_mutex; DWORD n_Thread=0; DWORD n_Buffer_or_Critical;HANDLE h_SemaphoreMAX_THREAD_NUM; void Produce(void *p); void Consume(void *p); bool IfInOtherRuquest(int); int FindProducePosition(); int FindBufferPosition(int); int main(void) DWORD wait_for_all; ifst

11、ream inFile; for(int i=0;in_Buffer_or_Critical; inFile.get(); printf(“输入文件是:nn“); printf(“ %d_Buffer_or_Critical n“,(int)n_Buffer_or_Critical); while(inFile) inFileThread_Infon_Thread.serial; inFileThread_Infon_Thread.entity; inFileThread_Infon_Thread.delay; char c; inFile.get(c); while(c!=n inFile.

12、get(c); n_Thread+; for(j=0;jserial; m_delay=(DWORD)(ThreadInfo*)(p)-delay*INTE_PER_SEC); Sleep(m_delay); printf(“producer %2d sends the produce require.n“,m_serial); wait_for_semaphore=WaitForSingleObject(empty_semaphore,-1); wait_for_mutex=WaitForSingleObject(h_mutex,-1); int ProducePos=FindProduce

13、Position(); ReleaseMutex(h_mutex); printf(“producer %2d begin to produce at position %2d.n“,m_serial,ProducePos); Buffer_CriticalProducePos=m_serial; printf(“producer %2d finish producing.n“,m_serial); printf(“position%2d:%3d n“,ProducePos,Buffer_Critical ProducePos); ReleaseSemaphore(h_Semaphorem_s

14、erial,n_Thread,NULL); void Consume(void*p) DWORD wait_for_semaphore,m_delay; int m_serial,m_requestNum; int m_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; Sl

15、eep(m_delay); for(i=0;ithread_requesti=-1; if(!IfInOtherRequest(m_thread_requesti) Buffer_CriticalBufferPos=0; printf(“consumer %2d finish consuming %2d .n “,m_serial,m_thread_requesti); printf(“ position%2d:%3dn“,BufferPos,Buffer_CriticalBufferPos); ReleaseSemaphore(empty_semaphore,1,NULL); else pr

16、intf(“consumer %2d finish consuming product %2d :n “,m_serial,m_thread_requesti); LeaveCriticalSection( 其中测试数据文件的例子: 5 1P 3 2P 4 3C 4 4P 2 5C 3 数据结构的说明及程序主体部分的注释1. 定义一个结构,记录在测试文件中指定的每一个线程的参数(1)用一个整型数组Buffer_Critical来代表缓冲区。不管是生产产品还是 对已有的产品的消费都需要访问该组缓冲区。(2)进程信息 ThreadInfo数据结构,包含线程的各个信息。struct ThreadInfo int serial;

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号