免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 6340 | 回复: 47
打印 上一主题 下一主题

[C++] “生产者-消费者”模型的一个小问题。 [复制链接]

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-10-28 20:52 |只看该作者 |倒序浏览
问题:生产者在把message压入message_buffer的时候,使用“阻塞”或者“非阻塞”模式都没什么区别吧?

目标:我想在每次压入message_buffer的时候都单独打开一个thread,然后让这个新线程来负责具体的压入工作,这样生产者就变成了“非阻塞”模式。

反正就是想尽力利用系统的多核心来提高处理速度。

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
2 [报告]
发表于 2015-10-28 20:58 |只看该作者
你的message queue有尺寸上限么?没有就没关系,反正push queue也不会block。

但是“在每次压入message_buffer的时候都单独打开一个thread”这句我有点理解不能。

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
3 [报告]
发表于 2015-10-28 21:09 |只看该作者
回复 2# windoze


意思是说我想这样:boost::thread o_thread((boost::bind(&message_buffer::put_operation, this, p_message)));
  1. #include <queue>
  2. #include <boost/shared_ptr.hpp>
  3. #include "message.hpp"

  4. class message_buffer: public boost::noncopyable
  5. {
  6.     private:

  7.         boost::mutex                  o_mutex;
  8.         boost::condition_variable_any o_get_cond;

  9.         std::queue<boost::shared_ptr<message>> o_queue;

  10.         int current_size = 0;

  11.     public:
  12.         void put(boost::shared_ptr<message> p_message)
  13.         {
  14.             boost::thread o_thread((boost::bind(&message_buffer::put_operation, this, p_message)));
  15.         }

  16.         void get(boost::shared_ptr<message> p_message)
  17.         {
  18.             mutex::lock_guard o_lock_guard(this->o_mutex);

  19.             while (this->is_empty())
  20.             {
  21.                 this->o_get_cond.wait(this->o_mutex);
  22.             }

  23.             this->current_size--;

  24.             p_message = *(this->o_queue.front());

  25.             this->o_queue.pop();
  26.         }

  27.     private:
  28.         bool is_empty(void)
  29.         {
  30.             return this->current_size == 0;
  31.         }

  32.         void put_operation(boost::shared_ptr<message> p_message)
  33.         {
  34.             {
  35.                 mutex::lock_guard o_lock_guard(this->o_mutex);

  36.                 this->o_queue.push(p_message);

  37.                 this->current_size++;
  38.             }

  39.             this->o_get_cond.notify_one()
  40.         }
  41. }

复制代码

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
4 [报告]
发表于 2015-10-28 21:10 |只看该作者
没怎么弄过这个,不知道这样行不行,我正在冥思苦想各种提升性能(发挥硬件性能)的方法。

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
5 [报告]
发表于 2015-10-28 21:13 |只看该作者
突然发现个问题:如果queue的push操作不会block,那我就不用这么折腾了,直接就push就行了。

果然学艺不精。。。

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
6 [报告]
发表于 2015-10-28 22:07 |只看该作者
回复 5# fender0107401

就算push会block你也不用折腾啊,无非就是加一个full_condition在push的时候wait就好了。

不过有个问题,你这个message_buffer怎么关闭?

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
7 [报告]
发表于 2015-10-29 08:49 |只看该作者
本帖最后由 fender0107401 于 2015-10-29 08:54 编辑

回复 6# windoze

1.我不想wait,我就想生产者直接put一下,然后put这个函数打开一个新的线程以后就返回(一点都不想等,我担心producer在put的时候正好有几个consumer在等着get会影响producer的速度),然后这个线程把message给push进去。

2.“不过有个问题,你这个message_buffer怎么关闭?”这句我不太明白,关闭是什么意思?


   

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
8 [报告]
发表于 2015-10-29 09:31 |只看该作者
本帖最后由 wlmqgzm 于 2015-10-29 09:34 编辑

高性能"lock-free"无锁队列的应用:  boost::lockfree::spsc_queue  一个无等待的单生产者/单消费者队列
2个线程之间, 必须要交换数据的问题,  其中一个线程是管理线程, 一个是acceptor线程.
对于此类问题, 传统的方式就是: 生产者和消费者模式, 二者之间, 通过队列QUEUE, 双方都加锁(mutex)处理队列.
我的解决方案是采用  Boost 高性能 无锁队列来实现,  只用了三条代码就解决了此问题.
无锁队列的优势:
它将保证线程无限次调用这个方法都能够在有限步内完成,而不会因为其他线程被阻塞而导致本线程无法在有限步内完成,即“无锁”。
保证在任何情况下所有并发中有一个操作能够得到执行, 不必考虑"多线进程的优先级反转等策略".

#include <boost/lockfree/spsc_queue.hpp>
boost::lockfree::spsc_queue<unsigned int, boost::lockfree::capacity<65536> >  closed_ip_queue;  
closed_ip_queue.push( int_ip );
closed_ip_queue.pop( int_closed_ip )
还要加上检查返回值的代码

下面是Boost对于spsc_queue的解释:
boost::lockfree::spsc_queue
await-free single-producer/single-consumer queue (commonly known as ringbuffer)
一个无等待的单生产者/单消费者队列(通常被称为环形缓冲区)  
这个非常猛的东西, 号称无锁, 无等待, 双并发.......

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
9 [报告]
发表于 2015-10-29 09:34 |只看该作者
回复 8# wlmqgzm

我刚刚在网上找到了这个,http://www.boost.org/doc/libs/1_ ... lockfree/queue.html

你发的这个是<boost/lockfree/spsc_queue.hpp>,我找到那个是<boost/lockfree/queue.hpp>。

我感觉用这个以后,就不用自己写P/C模型了。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
10 [报告]
发表于 2015-10-29 09:36 |只看该作者
本帖最后由 wlmqgzm 于 2015-10-29 10:00 编辑

回复 9# fender0107401

这个我用了多年了.   记得大约6-12个月前看windoze的开源代码, 有几个队列,  里面一堆的锁, 然后给他回复, 粘贴了Boost手册上的例子, 没有被采纳,

另外, Boost手册 lock-free queue的例子有错误, 在直接拿来测试的时候, 编译应该不会通过, 要自己修改,

这个也是多数人实验, 就编译错误, 然后放弃这个库, 因此lock-free queue在国内使用不多的原因之一,

修改方法,参考我的三行代码.  里面要增补定义boost::lockfree::capacity<XXX>

#include <boost/lockfree/spsc_queue.hpp>
boost::lockfree::spsc_queue<unsigned int, boost::lockfree::capacity<65536> >  closed_ip_queue;  
closed_ip_queue.push( int_ip );
closed_ip_queue.pop( int_closed_ip )
还要加上检查返回值的代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP