ACE_Message_Queue和spawn实现(生产者/消费者)(V2.00)
參考这里用到了线程管理。參考:http://blog.csdn.net/calmreason/article/details/36399697
以下的两个线程共享一个消息队列,一个用来放整数到队列,一个从队列里取消息出来。
此程序在控制台不停的输出递增数字,主要是内存不会泄露
用到了多线程、ACE_Message_Queue、ACE_Message_Block、ACE_Thread_Manager::instance()->spawn等
#include <iostream>
using namespace std;
#include "boost/lexical_cast.hpp"
using namespace boost;
#include "ace/Thread_Manager.h"
#include "ace/Message_Queue.h" void* create_vairous_record(void* ace_message_queue); void* get_vairous_record(void* ace_message_queue); int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{ ACE_Message_Queue<ACE_MT_SYNCH>* various_record_queue = new ACE_Message_Queue<ACE_MT_SYNCH>; ACE_Thread_Manager::instance()->spawn(
ACE_THR_FUNC(create_vairous_record),
various_record_queue,
THR_NEW_LWP | THR_DETACHED); ACE_Thread_Manager::instance()->spawn(
ACE_THR_FUNC(get_vairous_record),
various_record_queue,
THR_NEW_LWP | THR_DETACHED); ACE_Thread_Manager::instance()->wait(); return 0;
} void* create_vairous_record(void* ace_message_queue)
{ ACE_Message_Queue<ACE_MT_SYNCH>* p_queue = (ACE_Message_Queue<ACE_MT_SYNCH>*)ace_message_queue;
int i=0;
while (i<10000000)
{
ACE_Message_Block* mbl = new ACE_Message_Block(10);//在这里创建消息
string temp = lexical_cast<string>(++i);
mbl->copy(temp.c_str());
p_queue->enqueue_tail(mbl);//消息被放到队列中(用指针引用消息实体)
}
return nullptr;
} void* get_vairous_record(void* ace_message_queue)
{ ACE_Message_Queue<ACE_MT_SYNCH>* p_queue = (ACE_Message_Queue<ACE_MT_SYNCH>*)ace_message_queue;
while (true)
{
ACE_Message_Block* mbl =nullptr;
p_queue->dequeue_head(mbl);//消息出队,出队的消息应该在用完之后被释放
if (mbl)
{
cout<<mbl->rd_ptr()<<endl;
mbl->release();//消息已经用完。释放消息
}
}
return nullptr; }
以下的程序实现:多个线程将连续整数分批放到ACE_Message_Queue中,一个消费者线程负责从中取出,并验证数据是否完整无误
#include <iostream>
#include <bitset>
#include <vector>
#include <memory>
using namespace std; #include "ace/Thread_Manager.h"
#include "ace/Message_Queue.h"
#include "ace/Message_Block.h"
#include "ace/Task.h"
#include "ace/OS.h" namespace global
{
const int total_number = 1000000;
int task_number = 2;
typedef int number_type;
} class Generator_Number : public ACE_Task<ACE_MT_SYNCH>
{
public:
Generator_Number(ACE_Message_Queue<ACE_MT_SYNCH>* msgq,const int i);
virtual int open(void *args = 0 );
~Generator_Number(void);
protected:
Generator_Number(const Generator_Number&);
Generator_Number& operator=(const Generator_Number&);
private:
int svc(void);
int mod_i_;
}; Generator_Number::Generator_Number(ACE_Message_Queue<ACE_MT_SYNCH>* msgq,const int i):mod_i_(i)
{
this->msg_queue(msgq);
std::cout<<"Generator_Number(const int "<<i<<")"<<std::endl;
} int Generator_Number::open(void *args )
{
return this->activate(THR_NEW_LWP | THR_DETACHED);
} int Generator_Number::svc(void)
{
std::cout<<"Generator_Number("<<this->mod_i_<<")::svc()"<<std::endl;
for (size_t i = this->mod_i_ ; i<global::total_number;i+=global::task_number)
{
ACE_Message_Block * blk = new ACE_Message_Block(20);
blk->copy(reinterpret_cast<const char*>(&i),sizeof(global::number_type));
this->msg_queue()->enqueue_tail(blk);
}
return 0;
} Generator_Number::~Generator_Number(void)
{
std::cout<<"~Generator_Number("<<this->mod_i_<<")"<<std::endl;
} void* out_put_queue(void* all_numbers_queue1)
{
ACE_Message_Queue<ACE_MT_SYNCH>* all_numbers_queue = (ACE_Message_Queue<ACE_MT_SYNCH>*)all_numbers_queue1;
bitset<global::total_number> all_number_bitset;
size_t count_got_message=0;
while(true)
{
if(!all_numbers_queue->is_empty())
{
ACE_Message_Block* blk = 0;
all_numbers_queue->dequeue_head(blk);
all_number_bitset.set(*reinterpret_cast<global::number_type*>(blk->rd_ptr()));
blk->release();
if(++count_got_message == global::total_number)
{
break;
}
}
else
{
std::cout<<"now sleep 1"<<std::endl;
ACE_Time_Value t(0,3000);
ACE_OS::sleep(t);
}
}
global::number_type check =0;
bool wright_flag = true;
for (size_t j=0; j!= global::total_number;++j)
{
if (0 == all_number_bitset[j])
{
wright_flag = false;
break;
}
}
std::cout<<std::endl;
std::cout<<"check result:"<<wright_flag<<std::endl;
return 0;
}
#include "boost/timer.hpp"
using namespace boost; int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
cout<<"total_number:"<<global::total_number<<endl;
timer t;
ACE_Message_Queue<ACE_MT_SYNCH>* all_numbers_queue = new ACE_Message_Queue<ACE_MT_SYNCH>; vector<shared_ptr<Generator_Number>> gener_array; for (int i=0;i<global::task_number;++i)
{
gener_array.push_back(shared_ptr<Generator_Number>(new Generator_Number(all_numbers_queue,i)));
}
for (vector<shared_ptr<Generator_Number>>::const_iterator citer = gener_array.cbegin();
citer!=gener_array.cend();
++citer)
{
(*citer)->open();
} ACE_Thread_Manager::instance()->spawn(
ACE_THR_FUNC(out_put_queue),
all_numbers_queue,
THR_NEW_LWP | THR_DETACHED); ACE_Thread_Manager::instance()->wait();
cout<<t.elapsed()<<"s"<<endl;
return 0;
}
输出例如以下:
total_number:1000000
Generator_Number(const int 0)
Generator_Number(const int 1)
Generator_Number(0)::svc()
Generator_Number(1now sleep 1
)::svc()
now sleep 1
now sleep 1
now sleep 1
now sleep 1
now sleep 1
now sleep 1
now sleep 1
now sleep 1
now sleep 1
check result:1
0.944s
~Generator_Number(0)
~Generator_Number(1)
请按随意键继续. . .
ACE_Message_Queue
高水位低水位
http://blog.163.com/ecy_fu/blog/static/4445126200964115620862/
注意事项
ACE_Message_Queue和spawn实现(生产者/消费者)(V2.00)的更多相关文章
- python_way ,day11 线程,怎么写一个多线程?,队列,生产者消费者模型,线程锁,缓存(memcache,redis)
python11 1.多线程原理 2.怎么写一个多线程? 3.队列 4.生产者消费者模型 5.线程锁 6.缓存 memcache redis 多线程原理 def f1(arg) print(arg) ...
- 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼
1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...
- java ReentrantLock结合条件队列 实现生产者-消费者模式 以及ReentratLock和Synchronized对比
package reentrantlock; import java.util.ArrayList; public class ProviderAndConsumerTest { static Pro ...
- Queue和BlockingQueue的使用以及使用BlockingQueue实现生产者-消费者
Java提供了两种新的容器类型:Queue和BlockingQueue. Queue用于保存一组等待处理的元素.它提供了几种实现,包括:ConcurrentLinkedQueue,这是一个先进先出的并 ...
- python进阶:Python进程、线程、队列、生产者/消费者模式、协程
一.进程和线程的基本理解 1.进程 程序是由指令和数据组成的,编译为二进制格式后在硬盘存储,程序启动的过程是将二进制数据加载进内存,这个启动了的程序就称作进程(可简单理解为进行中的程序).例如打开一个 ...
- 多线程学习-基础(十二)生产者消费者模型:wait(),sleep(),notify()实现
一.多线程模型一:生产者消费者模型 (1)模型图:(从网上找的图,清晰明了) (2)生产者消费者模型原理说明: 这个模型核心是围绕着一个“仓库”的概念,生产者消费者都是围绕着:“仓库”来进行操作, ...
- 第三节: List类型的介绍、生产者消费者模式、发布订阅模式
一. List类型基础 1.介绍 它是一个双向链表,支持左进.左出.右进.右出,所以它即可以充当队列使用,也可以充当栈使用. (1). 队列:先进先出, 可以利用List左进右出,或者右进左出(Lis ...
- 并发、并行、同步、异步、全局解释锁GIL、同步锁Lock、死锁、递归锁、同步对象/条件、信号量、队列、生产者消费者、多进程模块、进程的调用、Process类、
并发:是指系统具有处理多个任务/动作的能力. 并行:是指系统具有同时处理多个任务/动作的能力. 并行是并发的子集. 同步:当进程执行到一个IO(等待外部数据)的时候. 异步:当进程执行到一个IO不等到 ...
- 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型
本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...
- Python3学习之路~9.4 队列、生产者消费者模型
一 队列queue 当必须在多个线程之间安全地交换信息时,队列在线程编程中特别有用. 队列的作用:1.解耦,使程序直接实现松耦合 2.提高处理效率 列表与队列都是有顺序的,但是他们之间有一个很大的区别 ...
随机推荐
- str和unicode类
在py2中,分为两类,str和unicode 而在py3中,分为两类,byte和str py2中的str等同于py3中的byte 首先明确一点,我们编辑好一段文本,python并不知道我们的文本是以什 ...
- RabbitMQ Headers Exchange示例
(1).发布者 var connectionFactory = new ConnectionFactory() { HostName="192.168.205.128",UserN ...
- Linux下USB suspend/resume源码分析【转】
转自:http://blog.csdn.net/aaronychen/article/details/3928479 Linux下USB suspend/resume源码分析 Author:aaron ...
- Tomcat优化步骤【转】
一.Tomcat的缺省是多少,怎么修改 Tomcat的缺省端口号是8080.修改Tomcat端口号:1.找到Tomcat目录下的conf文件夹2.进入conf文件夹里面找到server.xml文件3. ...
- OpenLayers 3 之 地图图层数据来源(ol.source)详解
原文地址 source 是 Layer 的重要组成部分,表示图层的来源,也就是服务地址.除了在构造函数中制定外,可以使用 layer.setSource(source) 稍后指定.一.包含的类型 ol ...
- django Rest Framework---缓存通过drf-extensions扩展来实现
什么情况下使用缓存 1.不经常更新的数据 2.用户经常访问的一些页面,比如商品列表页.商品详情页等 3.用户经常修改的一些操作:购物车.订单中心等 关于DRF缓存扩展可以参考文档:http://chi ...
- win7(x64)安装scrapy框架
Scrapy(官网http://scrapy.org/)是Python开发网络爬虫,一个极好的开源工具.本次安装Scrapy确实不易啊.居然花了2天多时间,需要的支持包比较多,这些支持包相互之间的依赖 ...
- 在局域网内实现https安全访问
在局域网内实现https安全访问 准备原料 服务器 resin (当然也可以是tomcat,这里以resin为例) 安装jdk 域名 (随便写一个就行,因为是内网使用,不会被校验) 生成证书 第一步: ...
- java 异常匹配
抛出异常的时候,异常处理系统会安装代码书写顺序找出"最近"的处理程序. 找到匹配的程序后,它就认为异常将得到清理,然后就不再继续查找. 查找的时候并不要求抛出的异常同处理程序的异常 ...
- (转)Python函数式编程——map()、reduce()
转自:http://www.jianshu.com/p/7fe3408e6048 1.map(func,seq1[,seq2...]) Python 函数式编程中的map()函数是将func作用于se ...