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.提高处理效率 列表与队列都是有顺序的,但是他们之间有一个很大的区别 ...
随机推荐
- Django进阶之session
基于cookie做用户验证时:敏感信息不适合放在cookie中 session依赖cookie session原理 cookie是保存在用户浏览器端的键值对 session是保存在服务器端的键值对 s ...
- python中的*号
from:https://www.douban.com/note/231603832/ 传递实参和定义形参(所谓实参就是调用函数时传入的参数,形参则是定义函数是定义的参数)的时候,你还可以使用两个特殊 ...
- MYSQL 的 MASTER到MASTER的主主循环同步
MYSQL 的 MASTER到MASTER的主主循环同步 刚刚抽空做了一下MYSQL的主主同步.把步骤写下来,至于会出现的什么问题,以后随时更新.这里我同步的数据库是TEST1.环境描述. 主 ...
- Ansible Tower系列 四(使用tower执行一个命令)【转】
在主机清单页面中,选择一个主机清单,进入后,选择hosts里的主机 Paste_Image.png 点击 RUN COMMANDS MODULE 选择 commandARGUMENTS 填写 ifco ...
- 大数据系列之分布式计算批处理引擎MapReduce实践-排序
清明刚过,该来学习点新的知识点了. 上次说到关于MapReduce对于文本中词频的统计使用WordCount.如果还有同学不熟悉的可以参考博文大数据系列之分布式计算批处理引擎MapReduce实践. ...
- mysql添加远程访问权限
GRANT 权限列表 ON 数据库.表 TO 用户账号 @ 用户ip IDENTIFIED BY 用户密码 授权命令; 权限列表:允许用户执行的操作权限. 包含select,insert,update ...
- java 内部类使用 .this 和 .new
如果需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this,这样产生的引用自动地具有正确的类型,这一点在编译器就被知晓并受到检查,因此并没有运行时开销 //: innerclasses ...
- BZOJ 1934 Vote 善意的投票(最小割+二分图)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1934 题目大意: 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题 ...
- Grafana 短信报警
一.分析 需求 Grafana支持短信渠道报警 要求 使用开发提供的短信API接口 请求url: http://192.168.1.1:8088/alerting/sendSms?mobile=手机号 ...
- C++Primer #7 类
类的定义 简单的来说类就是数据和它的操作的一种封装,内部提供接口函数 类的成员函数的声明必须在类的内部,而它的定义则既可以放在类的内部也可以放在类的外部.(一般在类内进行声明,类外实现函数定义) 定义 ...