生产者消费者设计模式

上传人:第*** 文档编号:32826179 上传时间:2018-02-12 格式:DOC 页数:13 大小:55KB
返回 下载 相关 举报
生产者消费者设计模式_第1页
第1页 / 共13页
生产者消费者设计模式_第2页
第2页 / 共13页
生产者消费者设计模式_第3页
第3页 / 共13页
生产者消费者设计模式_第4页
第4页 / 共13页
生产者消费者设计模式_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《生产者消费者设计模式》由会员分享,可在线阅读,更多相关《生产者消费者设计模式(13页珍藏版)》请在金锄头文库上搜索。

1、基于 C+11 实现生产者消费者设计模式本文将综合运用 C+11 中的新的基础设施( 主要是多线程、锁、条件变量)来阐述一个经典问题生产者消费者模式,并给出完整的解决方案。生产者消费者问题是多线程并发中一个非常经典的问题,相信学过操作系统课程的同学都清楚这个问题的根源。本文将就四种情况分析并介绍生产者和消费者问题,它们分别是:单生产者-单消费者模式,单生产者-多消费者模式,多生产者-单消费者模式,多生产者-多消费者模式,我会给出四种情况下的 C+11 并发解决方案,如果文中出现了错误或者你对代码有异议,欢迎交流。1 单生产者-单消费者模式顾名思义,单生产者-单消费者模式中只有一个生产者和一个消

2、费者,生产者不停地往产品库中放入产品,消费者则从产品库中取走产品,产品库容积有限制,只能容纳一定数目的产品,如果生产者生产产品的速度过快,则需要等待消费者取走产品之后,产品库不为空才能继续往产品库中放置新的产品,相反,如果消费者取走产品的速度过快,则可能面临产品库中没有产品可使用的情况,此时需要等待生产者放入一个产品后,消费者才能继续工作。C+11 实现单生产者单消费者模式的代码如下:#include #include #include #include #include #include static const int kItemRepositorySize = 10; / Item bu

3、ffer size.static const int kItemsToProduce = 1000; / How many items we plan to produce.struct ItemRepository int item_bufferkItemRepositorySize; / 产品缓冲区, 配合 read_position 和 write_position 模式环形队列.size_t read_position; / 消费者读取产品位置.size_t write_position; / 生产者写入产品位置.std:mutex mtx; / 互斥量, 保护产品缓冲区std:con

4、dition_variable repo_not_full; / 条件变量, 指示产品缓冲区不为满.std:condition_variable repo_not_empty; / 条件变量, 指示产品缓冲区不为空. gItemRepository; / 产品库全局变量, 生产者和消费者操作该变量.typedef struct ItemRepository ItemRepository;void ProduceItem(ItemRepository *ir, int item)std:unique_lock lock(ir-mtx);while(ir-write_position + 1) %

5、 kItemRepositorySize)= ir-read_position) / item buffer is full, just wait here.std:cout repo_not_full).wait(lock); / 生产者等待产品库缓冲区不为满 这一条件发生.(ir-item_buffer)ir-write_position = item; / 写入产品.(ir-write_position)+; / 写入位置后移.if (ir-write_position = kItemRepositorySize) / 写入位置若是在队列最后则重新设置为初始位置.ir-write_pos

6、ition = 0;(ir-repo_not_empty).notify_all(); / 通知消费者产品库不为空.lock.unlock(); / 解锁.int ConsumeItem(ItemRepository *ir)int data;std:unique_lock lock(ir-mtx);/ item buffer is empty, just wait here.while(ir-write_position = ir-read_position) std:cout repo_not_empty).wait(lock); / 消费者等待 产品库缓冲区不为空这一条件发生.data

7、= (ir-item_buffer)ir-read_position; / 读取某一产品(ir-read_position)+; / 读取位置后移if (ir-read_position = kItemRepositorySize) / 读取位置若移到最后,则重新置位.ir-read_position = 0;(ir-repo_not_full).notify_all(); / 通知消费者产品库不为满.lock.unlock(); / 解锁.return data; / 返回产品.void ProducerTask() / 生产者任务for (int i = 1; i write_positi

8、on = 0; / 初始化产品写入位置.ir-read_position = 0; / 初始化产品读取位置.int main()InitItemRepository(std:thread producer(ProducerTask); / 创建生产者线程.std:thread consumer(ConsumerTask); / 创建消费之线程.producer.join();consumer.join();2 单生产者-多消费者模式与单生产者和单消费者模式不同的是,单生产者-多消费者模式中可以允许多个消费者同时从产品库中取走产品。所以除了保护产品库在多个读写线程下互斥之外,还需要维护消费者取走

9、产品的计数器,代码如下:#include #include #include #include #include #include static const int kItemRepositorySize = 4; / Item buffer size.static const int kItemsToProduce = 10; / How many items we plan to produce.struct ItemRepository int item_bufferkItemRepositorySize;size_t read_position;size_t write_positio

10、n;size_t item_counter;std:mutex mtx;std:mutex item_counter_mtx;std:condition_variable repo_not_full;std:condition_variable repo_not_empty; gItemRepository;typedef struct ItemRepository ItemRepository;void ProduceItem(ItemRepository *ir, int item)std:unique_lock lock(ir-mtx);while(ir-write_position +

11、 1) % kItemRepositorySize)= ir-read_position) / item buffer is full, just wait here.std:cout repo_not_full).wait(lock);(ir-item_buffer)ir-write_position = item;(ir-write_position)+;if (ir-write_position = kItemRepositorySize)ir-write_position = 0;(ir-repo_not_empty).notify_all();lock.unlock();int Co

12、nsumeItem(ItemRepository *ir)int data;std:unique_lock lock(ir-mtx);/ item buffer is empty, just wait here.while(ir-write_position = ir-read_position) std:cout repo_not_empty).wait(lock);data = (ir-item_buffer)ir-read_position;(ir-read_position)+;if (ir-read_position = kItemRepositorySize)ir-read_pos

13、ition = 0;(ir-repo_not_full).notify_all();lock.unlock();return data;void ProducerTask()for (int i = 1; i lock(gItemRepository.item_counter_mtx);if (gItemRepository.item_counter write_position = 0;ir-read_position = 0;ir-item_counter = 0;int main()InitItemRepository(std:thread producer(ProducerTask);

14、std:thread consumer1(ConsumerTask); std:thread consumer2(ConsumerTask);std:thread consumer3(ConsumerTask);std:thread consumer4(ConsumerTask);producer.join();consumer1.join();consumer2.join();consumer3.join();consumer4.join();3 多生产者-单消费者模式与单生产者和单消费者模式不同的是,多生产者-单消费者模式中可以允许多个生产者同时向产品库中放入产品。所以除了保护产品库在多个

15、读写线程下互斥之外,还需要维护生产者放入产品的计数器,代码如下:#include #include #include #include #include #include static const int kItemRepositorySize = 4; / Item buffer size.static const int kItemsToProduce = 10; / How many items we plan to produce.struct ItemRepository int item_bufferkItemRepositorySize;size_t read_position;size_t write_position;size_t item_counter;std:mutex mtx;std:mutex item_counter_mtx;std:condition_variable repo_not_full;std:condition_variable repo_not_empty; gItemRepository;typedef struct ItemRepository ItemRepository;void ProduceItem(ItemRepository *ir, int item)std:unique_l

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

当前位置:首页 > 建筑/环境 > 工程造价

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