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.提高处理效率 列表与队列都是有顺序的,但是他们之间有一个很大的区别 ...
随机推荐
- Update Bits
Given two 32-bit numbers, N and M, and two bit positions, i and j. Write a method to set all bits be ...
- cancel_delayed_work和flush_scheduled_work【转】
转自:http://blog.chinaunix.net/uid-9688646-id-4052595.html 是不是觉得很玄?像思念一样玄?那好,我们来看点具体的,比如935行,INIT_DELA ...
- usb_control_msg函数用法和说明
usb_control_msg是没有用到urb的在USB中简单进行发送和接收的一种机制,用于少量的数据通信.原型为: 程序代码 linux+v2.6.35/drivers/usb/core/mess ...
- Flask源码解析:Flask上下文
一.上下文(Context) 什么是上下文: 每一段程序都有很多外部变量.只有像Add这种简单的函数才是没有外部变量的.一旦你的一段程序有了外部变量,这段程序就不完整,不能独立运行.你为了使他们运行, ...
- ASP.NET MVC 路由学习
参考 http://www.cnblogs.com/yaozhenfa/p/asp_net_mvc_route_2.html 说明 1."解决与物理路径的冲突"这段教程这里如果不起 ...
- css中width和padding-top实现正方形
.div{ width: 100%; height: 0; padding-top: 100% } 这个时候,padding-top的值与width相等,所以可以让div宽高一样,值为width的值
- OI 助手 | 简洁快速的 OI 工具箱 (原 竞赛目录生成)
原竞赛目录生成 (4.0 版本前) 开发者:abc2237512422 OI 助手是一个轻量简洁的 OI 工具箱.你可以使用它来快速进行 OI 竞赛中一些繁琐的操作,例如生成竞赛目录.对拍.它为你省去 ...
- IDEA / WebStorm / PhpStorm 添加jQuery自动提示,自动补全,提醒文档
应该是JetBrains系列IDE通用的方法,网上其他一些方法有的过时了,有的不全 默认情况下没有JQuery补全,按照以下方法添加 1. 打开Settings,Languages & Fra ...
- MyBatis使用示例
下面是一个简单的MyBatis使用DEMO. 整体结构 整体代码大致如下: POM依赖 需要引用两个jar包,一个是mybatis,另一个是mysql-connector-java,如果是maven工 ...
- 【LOJ】#2076. 「JSOI2016」炸弹攻击
题解 我冷静一下,话说如果去掉建筑和R的限制好像是模拟退火吧 然后开始写模拟退火了,起始点就随机一个敌人作为起始点 没对着数据写了一下获得了70pts,感到美滋滋 然后对着数据卡了很久--发现有个数据 ...