实验4生产者消费者问题报告_第1页
实验4生产者消费者问题报告_第2页
实验4生产者消费者问题报告_第3页
实验4生产者消费者问题报告_第4页
实验4生产者消费者问题报告_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

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

文档简介

1、南京信息工程大学 实验(实习)报告实验(实习)名称 生产者-消费者问题的模拟实现 实验(实习)日期 2014.11.30 得分 指导教师 陈遥 系 计算机 专业 计科 年级 12级 班次 2 姓名 唐薇 学号 20122308061 一、实验目的本实验的目的是通过编写和调试一个解决生产者消费者问题的简单模拟程序,进一步深入理解课堂教学中讲授的进程同步问题,以及用于解决同步问题的信号量机制的基本思想,即通过研究进程同步和信号量机制实现生产者消费者问题的并发控制,以便阶段性地巩固学习成果。二、实验内容(1)概述说明:有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1-20这20个整型数。编

2、制程序模拟解决生产者-消费者同步问题。具体设计要求:(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费线程的标识符。(2)生产者和消费者各有两个以上。(3)多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码。(2)设计原理通过一个有界缓冲区把生产者和消费者联系起来。假定生产者和消费者的优先级是相同的,只要缓冲区未满,生产者就可以生产产品并将产品送入缓冲区。类似地,只要缓冲区未空,消费者就可以从缓冲区中取走产品。应该禁止生产者向满的缓冲区送入产品,同时也应该禁止消费者从空的缓冲区中取出产品,这一机制由生产者线程和消费者线程之间的互斥

3、关系来实现。与计算打印两进程同步关系相同,生产者和消费者两进程Producer和Consumer之间应满足下列两个同步条件: 只有在缓冲池中至少有一个缓冲区已存入消息后,消费者才能从中提取信息,否则消费者必须等待。 只有缓冲池中至少有一个缓冲区是空时,生产者才能把消息放入缓冲区,否则生产者必须等待。为了满足第一个同步条件,设置一个同步信号量full,它代表的资源是缓冲区满,它的初始值为0,它的值为n时整个缓冲池满。这个资源是消费者进程Consumer所有,Consumer进程可以申请该资源,对它施加P操作,而Consumer进程的合作进程生产者进程Producer对它施加V操作。同样为了满足第

4、二个同步条件,设置另一个同步信号量empty,它代表的资源是缓冲空区,它的初始值为n,表示缓冲池中所有缓冲区空。信号量full表示可用缓冲区数量,信号量empty表示缓冲区数量,设置整型变量:存入指针in和取出指针out。为解决生产者/消费者问题,应该设置两个资源信号量,其中一个表示空缓冲区的数目,用g_hFullSemaphore表示,其初始值为有界缓冲区的大小SIZE_OF_BUFFER;另一个表示缓冲区中产品的数目,用g_hEmptySemaphore表示,其初始值为0。另外,由于有界缓冲区是一个临界资源,必须互斥使用,所以还需要在设置一个互斥信号量g_hMutex,初始值为1.P原语的

5、主要动作是: sem(信号量)减1; 若sem减一后仍大于或等于零,则进程继续执行; 若sem减一后小于零,则该进程被阻塞后入与该信号相对应的队列中,然后转进程调度。V原语的操作主要动作是: sem加1; 若相加结果大于零,进程继续执行;若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程然后再返回原进程继续执行或转进程调度。采用的同步方法:1)利用函数CreateMutex(NULL,FALSE,NULL)创建互斥信号量g_hMutex,表示缓冲区当前的状态,若为true时,则表示缓冲区正被别的进程使用。三个参数表示的意义分别为:指向安全属性的指针,初始化互斥对象的所有者,指向互斥对

6、象名的指针。2)利用函数CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL)创建缓冲区空的信号量g_hFullSemaphore,值为true时表示缓冲区已满。四个参数分别为:表示是否允许继承、设置信号机的初始计数、设置信号机的最大计数、指定信号机对象的名称(-1是因为计数从开始)。3)利用函数CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL)创建缓冲区满的信号量g_hEmptySemaphore,该值为true时表示缓冲区为空。程序清单 1.存储结构定义 利用信号量解决生产者消费者问题

7、 const unsigned short SIZE_OF_BUFFER = 20; /缓冲区长度 unsigned short ProductID = 0; /产品号 unsigned short ConsumeID = 0; /将被消耗的产品号 unsigned short in = 0; /产品进缓冲区时的缓冲区下标 unsigned short out = 0; /产品出缓冲区时的缓冲区下标 int g_bufferSIZE_OF_BUFFER; /缓冲区是个循环队列 bool g_continue = true; /控制程序结束 HANDLE g_hMutex; /用于线程间的互斥

8、HANDLE g_hFullSemaphore; /当缓冲区满时迫使生产者等待 HANDLE g_hEmptySemaphore; /当缓冲区空时迫使消费者等待 DWORD WINAPI Producer(LPVOID); /生产者线程 DWORD WINAPI Consumer(LPVOID); /消费者线程 2.算法相关的函数 (1)创建各个互斥信号以及生产者线程和消费者线程的函数在如下主函数里面所示: int main() /创建各个互斥信号 g_hMutex = CreateMutex(NULL,FALSE,NULL); g_hFullSemaphore=CreateSemaphore

9、(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL); g_hEmptySemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL); /调整下面的数值,可以发现,当生产者个数多于消费者个数时, /生产速度快,生产者经常等待消费者;反之,消费者经常等待。 const unsigned short PRODUCERS_COUNT = 3; /生产者的个数 const unsigned short CONSUMERS_COUNT = 1; /消费者的个数 /总的线程数 const unsigned shor

10、t THREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT; HANDLE hThreadsTHREADS_COUNT; /各线程的handle DWORD producerIDPRODUCERS_COUNT; /生产者线程的标识符 DWORD consumerIDCONSUMERS_COUNT; /消费者线程的标识符 /创建生产者线程 for (int i=0; i PRODUCERS_COUNT;+i) hThreadsi=CreateThread(NULL,0,Producer,NULL,0,&producerIDi); if (hThreadsi=N

11、ULL) return -1; /创建消费者线程 for ( i=0; iCONSUMERS_COUNT;+i) hThreadsi=CreateThread(NULL,0,Consumer,NULL,0 ,&consumerIDi); if (hThreadsi=NULL) return -1; while(g_continue) if(getchar() /按回车后终止程序运行 g_continue = false; return 0; 生产者生产一个产品的函数: /生产一个产品。简单模拟了一下,仅输出新产品的ID号 void Produce() std:cerr Producing +P

12、roductID * ; std:cerr Succeed std:endl; (3)把新生产的产品放入缓冲区的函数: /把新生产的产品放入缓冲区 void Append() std:cerr Appending a product * ; g_bufferin = ProductID; in = (in+1)%SIZE_OF_BUFFER; std:cerr Succeed std:endl; (4)输出缓冲区当前的状态的代码: /输出缓冲区当前的状态 for (int i=0; iSIZE_OF_BUFFER;+i) std:cout i : g_bufferi; if (i=in) st

13、d:cout - 生产; if (i=out) std:cout - 消费; std:cout std:endl; 从缓冲区中取出一个产品的函数: /从缓冲区中取出一个产品 void Take() std:cerr Taking a product * ; ConsumeID = g_bufferout; out = (out+1)%SIZE_OF_BUFFER; 利用信号量解决生产者消费者问题 std:cerr Succeed std:endl; (5)输出缓冲区当前的状态的代码: /输出缓冲区当前的状态 for (int i=0; iSIZE_OF_BUFFER;+i) std:cout

14、i : g_bufferi; if (i=in) std:cout - 生产; if (i=out) std:cout - 消费; std:cout std:endl; (6)消耗一个产品的函数: /消耗一个产品 void Consume() std:cerr Consuming ConsumeID * ; std:cerr Succeed std:endl; 3.生产者和消费者算法 (1)生产者算法: /生产者 DWORD WINAPI Producer(LPVOID lpPara) while(g_continue) WaitForSingleObject(g_hFullSemaphore

15、,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Produce(); Append(); Sleep(1500); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hEmptySemaphore,1,NULL); return 0; (2)消费者算法: /消费者 DWORD WINAPI Consumer(LPVOID lpPara) while(g_continue) WaitForSingleObject(g_hEmptySemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Take(); Consume(); Sleep(1500); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hFullSema

温馨提示

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

最新文档

评论

0/150

提交评论