BOOST 线程完全攻略 - 扩展 - 线程消息通讯
- // controlled_module_ex.hpp : controlled_module类的扩展
- // 增强线程之间消息通讯
- // 增加线程安全启动和安全关闭功能
- // 增加定时器功能
- #pragma once
- #include <boost/shared_ptr.hpp>
- #include <boost/any.hpp>
- #include "controlled_module.hpp"
- struct _command
- {
- typedef boost::shared_ptr<_command> CCmdPtr;
- unsigned int nCmd;
- boost::any anyParam;
- };
- struct _wait_command
- {
- boost::any par;
- unsigned int command;
- void * event;
- boost::shared_ptr<boost::any> resp;
- };
- class controlled_module_ex;
- struct _notify
- {
- controlled_module_ex * sender;
- int id;
- boost::any par;
- };
- #define BM_RESERVE 1000
- #define BM_RING_START BM_RESERVE+1
- #define BM_RING_STOP BM_RESERVE+2
- #define BM_RING_SETTIME BM_RESERVE+3
- #define BM_RING_SETPARENT BM_RESERVE+4
- #define BM_RING_CYCLE BM_RESERVE+5
- #define BM_RING_PROCESS BM_RESERVE+6
- #define BM_RING_PROCESSEND BM_RESERVE+7
- #define BM_RING_PROCESSFAIL BM_RESERVE+8
- #define BM_TIMER BM_RESERVE+9
- #define BM_COMMAND BM_RESERVE+10
- #define BM_NOTIFY BM_RESERVE+11
- #define BM_USER 9000
- class controlled_timer;
- class controlled_module_ex: public controlled_module
- {
- public:
- controlled_module_ex()
- {
- m_safe = false;
- }
- ~controlled_module_ex()
- {
- safestop();
- }
- public:
- template<typename T>
- bool postmessage(unsigned int nCmd, const boost::shared_ptr<T>& p)
- {
- if(this==0||!m_safe)return false;
- boost::mutex::scoped_lock lock(m_mutex_command);
- _command::CCmdPtr cmd(new _command);
- cmd->nCmd = nCmd;
- cmd->anyParam = p;
- m_list_command.push_back(cmd);
- return true;
- }
- boost::any execute(unsigned int command,boost::any par,int timeout=-1)
- {
- boost::shared_ptr<_wait_command> shared(new _wait_command);
- _wait_command & cmd = *shared;
- cmd.command = command;
- cmd.event = (void *)CreateEvent(0,FALSE,FALSE,0);
- cmd.par = par;
- cmd.resp = boost::shared_ptr<boost::any>(new boost::any);
- if(this->postmessage(BM_COMMAND,shared))
- {
- DWORD dw = WaitForSingleObject(cmd.event,timeout);
- CloseHandle(cmd.event);
- if(dw!=WAIT_OBJECT_0)
- return boost::any();
- else
- return *cmd.resp;
- }
- else
- {
- CloseHandle(cmd.event);
- return boost::any();
- }
- }
- void notify(_notify p)
- {
- this->postmessage(BM_NOTIFY,p);
- }
- bool postmessage(unsigned int nCmd,boost::any p)
- {
- if(this==0||!m_safe)
- return false;
- boost::mutex::scoped_lock lock(m_mutex_command);
- _command::CCmdPtr cmd(new _command);
- cmd->nCmd = nCmd;
- cmd->anyParam = p;
- m_list_command.push_back(cmd);
- return true;
- }
- bool postmessage(unsigned int nCmd)
- {
- if(this==0||!m_safe)
- return false;
- boost::mutex::scoped_lock lock(m_mutex_command);
- _command::CCmdPtr cmd(new _command);
- cmd->nCmd = nCmd;
- cmd->anyParam = 0;
- m_list_command.push_back(cmd);
- return true;
- }
- virtual bool work()
- {
- if(!getmessage())
- return false;
- else
- {
- Sleep(this->m_sleeptime);
- return true;
- }
- }
- virtual void message(const _command & cmd)
- {
- if(cmd.nCmd==BM_RING_START)
- {
- this->on_safestart();
- }
- else if(cmd.nCmd==BM_RING_STOP)
- {
- this->on_safestop();
- }
- else if(cmd.nCmd==BM_TIMER)
- {
- this->on_timer(boost::any_cast<controlled_timer*>(cmd.anyParam));
- }
- else if(cmd.nCmd==BM_COMMAND)
- {
- boost::shared_ptr<_wait_command> shared = boost::any_cast< boost::shared_ptr<_wait_command> >(cmd.anyParam);
- _wait_command & cmd = *shared;
- *cmd.resp = this->on_command(cmd.command,cmd.par);
- SetEvent((HANDLE)cmd.event);
- }
- else if(cmd.nCmd==BM_NOTIFY)
- {
- try
- {
- _notify par = boost::any_cast<_notify>(cmd.anyParam);
- this->on_notify(par);
- }
- catch(boost::bad_any_cast)
- {
- }
- }
- }
- virtual void release()
- {
- boost::mutex::scoped_lock lock(m_mutex_command);
- m_list_command.clear();
- }
- void safestart()
- {
- if(!islive())
- start();
- m_safe = true;
- m_safestart_event = (void*)CreateEvent(NULL,FALSE,FALSE,0);
- postmessage(BM_RING_START);
- ::WaitForSingleObject((HANDLE)m_safestart_event,INFINITE);
- CloseHandle(m_safestart_event);
- }
- void safestop()
- {
- if(this->islive())
- {
- m_safe = false;
- m_safestop_event = (void*)CreateEvent(NULL,FALSE,FALSE,0);
- {
- boost::mutex::scoped_lock lock(m_mutex_command);
- _command::CCmdPtr cmd(new _command);
- cmd->nCmd = BM_RING_STOP;
- cmd->anyParam = 0;
- m_list_command.push_back(cmd);
- }
- DWORD dw = ::WaitForSingleObject((HANDLE)m_safestop_event,3*1000);
- if(WAIT_OBJECT_0!=dw)
- {
- }
- CloseHandle(m_safestop_event);
- stop();
- }
- }
- virtual void on_timer(const controlled_timer * p){}
- virtual void on_safestart()
- {
- SetEvent(m_safestart_event);
- }
- virtual void on_safestop()
- {
- SetEvent(m_safestop_event);
- }
- virtual void on_notify(const _notify & p)
- {
- }
- protected:
- virtual boost::any on_command(const unsigned int command,const boost::any par)
- {
- return boost::any();
- }
- bool getmessage()
- {
- std::list<_command::CCmdPtr> cache;
- {
- boost::mutex::scoped_lock lock(m_mutex_command);
- while(!m_list_command.empty())
- {
- _command::CCmdPtr p = m_list_command.front();
- m_list_command.pop_front();
- cache.push_back(p);
- }
- }
- _command::CCmdPtr stop_command;
- std::list<_command::CCmdPtr>::iterator item;
- for(item = cache.begin();item!=cache.end();item++)
- {
- if((*(*item)).nCmd==BM_RING_STOP)
- {
- stop_command = *item;
- break;
- }
- }
- if(stop_command.get()==0)
- {
- while(!cache.empty())
- {
- _command::CCmdPtr p = cache.front();
- cache.pop_front();
- try
- {
- if((*p).nCmd!=BM_RING_START)
- {
- if(!this->m_safe)
- continue;
- }
- this->message(*p);
- }
- catch(boost::bad_any_cast &)
- {
- }
- }
- return true;
- }
- else
- {
- cache.clear();
- this->message(*stop_command);
- return false;
- }
- }
- private:
- void* m_safestart_event;
- void* m_safestop_event;
- bool m_safe;//在多线程,尤其牵涉到线程之间有类似socket级别关联时,当父线程safestop以后有可能会收到其他线程的postmessage,这时会引起线程死锁,这个m_safe就是解决这个问题的,当safestop以后不再接收新消息处理
- boost::mutex m_mutex_command;
- std::list<_command::CCmdPtr> m_list_command;
- };
- class controlled_timer: public controlled_module_ex
- {
- public:
- controlled_timer()
- {
- this->m_time = 0;
- this->m_parent = 0;
- this->m_step = 0;
- }
- ~controlled_timer(){
- }
- protected:
- controlled_module_ex* m_parent;
- int m_time;
- int m_step;
- public:
- void starttimer(int time,controlled_module_ex* parent)
- {
- this->safestart();
- this->postmessage(BM_RING_SETPARENT,parent);
- this->postmessage(BM_RING_SETTIME,time);
- }
- void stoptimer()
- {
- this->safestop();
- }
- public:
- virtual void on_safestop()
- {
- m_time = 0;
- controlled_module_ex::on_safestop();
- }
- virtual void message(const _command & cmd)
- {
- controlled_module_ex::message(cmd);
- if(cmd.nCmd==BM_RING_SETTIME)
- {
- int time = boost::any_cast<int>(cmd.anyParam);
- this->m_time = time/this->m_sleeptime;
- this->postmessage(BM_RING_CYCLE);
- }
- else if(cmd.nCmd==BM_RING_SETPARENT)
- {
- this->m_parent = boost::any_cast<controlled_module_ex*>(cmd.anyParam);
- }
- else if(cmd.nCmd==BM_RING_CYCLE)
- {
- if(m_time>0)
- {
- if(m_step>m_time)
- {
- m_parent->postmessage(BM_TIMER,this);
- m_step=0;
- }
- m_step++;
- }
- this->postmessage(BM_RING_CYCLE);
- }
- }
- };
1.向线程PostMessage
- #include "controlled_module_ex.hpp"
- class thdex: public controlled_module_ex
- {
- protected:
- virtual void message(const _command & cmd)
- {
- controlled_module_ex::message(cmd);
- if(cmd.nCmd==BM_USER+1)
- {
- cout << "get message" << endl;
- }
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- thdex t;
- t.safestart();
- t.postmessage(BM_USER+1);
- char buf[10];
- gets_s(buf,sizeof buf);
- t.safestop();
- return 0;
- }
- #include "controlled_module_ex.hpp"
- struct mystruct
- {
- string a;
- int b;
- };
- class thdex: public controlled_module_ex
- {
- protected:
- virtual void message(const _command & cmd)
- {
- controlled_module_ex::message(cmd);
- if(cmd.nCmd==BM_USER+1)
- {
- cout << "get integer:" << boost::any_cast<int>(cmd.anyParam) << endl;
- }
- if(cmd.nCmd==BM_USER+2)
- {
- cout << "get string:" << boost::any_cast<string>(cmd.anyParam) << endl;
- }
- if(cmd.nCmd==BM_USER+3)
- {
- mystruct par = boost::any_cast<mystruct>(cmd.anyParam);
- cout << "get mystruct:" << par.a << "," << par.b << endl;
- }
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- thdex t;
- t.safestart();
- t.postmessage(BM_USER+1,123);
- t.postmessage(BM_USER+2,string("hello world"));
- mystruct par;
- par.a = "hello world";
- par.b = 123;
- t.postmessage(BM_USER+3,par);
- char buf[10];
- gets_s(buf,sizeof buf);
- t.safestop();
- return 0;
- }
3.向线程PostMessage,并传递内存块参数
- #include "controlled_module_ex.hpp"
- struct mystruct
- {
- boost::shared_ptr<char> data;
- int datalen;
- };
- class thdex: public controlled_module_ex
- {
- protected:
- virtual void message(const _command & cmd)
- {
- controlled_module_ex::message(cmd);
- if(cmd.nCmd==BM_USER+1)
- {
- cout << "get sharedptr" << endl; //仅仅得到数据,得不到数据长度
- }
- if(cmd.nCmd==BM_USER+2)
- {
- mystruct par = boost::any_cast<mystruct>(cmd.anyParam);
- cout << "get sharedptr len:" << par.datalen << endl;
- }
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- thdex t;
- t.safestart();
- t.postmessage(BM_USER+1,boost::shared_ptr<char>(new char[1000]));
- mystruct par;
- par.datalen = 1000;
- par.data = boost::shared_ptr<char>(new char[par.datalen]);
- t.postmessage(BM_USER+2,par);
- char buf[10];
- gets_s(buf,sizeof buf);
- t.safestop();
- return 0;
- }
3.向线程SendMessage
- #include "controlled_module_ex.hpp"
- class thdex: public controlled_module_ex
- {
- protected:
- boost::any on_command(const unsigned int command,const boost::any par)
- {
- if(command==1)
- {
- cout << "on command" << endl;
- return 0;
- }
- if(command==2)
- {
- cout << "on command,par:" << boost::any_cast<string>(par) << endl;
- return 0;
- }
- if(command==3)
- {
- return true;
- }
- else
- return controlled_module_ex::on_command(command,par);
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- thdex t;
- t.safestart();
- t.execute(1,0);//等待子线程处理完成
- t.execute(2,string("hello world"));//带参数 等待子线程完成
- bool rs = boost::any_cast<bool>(t.execute(3,0));//等待子线程处理完成,并取得返回值
- cout << "get thread result:" << rs << endl;
- boost::any timeout = t.execute(4,0,1000);//等待子线程处理,超时1秒
- if(timeout.empty())
- cout << "timeout " << endl;
- char buf[10];
- gets_s(buf,sizeof buf);
- t.safestop();
- return 0;
- }
4.定时器
- #include "controlled_module_ex.hpp"
- class thdex: public controlled_module_ex
- {
- protected:
- virtual void on_timer(const controlled_timer *p)
- {
- cout << "ontimer" << endl;
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- thdex t;
- controlled_timer timer;
- t.safestart();
- timer.starttimer(1000,&t);
- char buf[10];
- gets_s(buf,sizeof buf);
- t.safestop();
- return 0;
- }
BOOST 线程完全攻略 - 扩展 - 线程消息通讯的更多相关文章
- BOOST 线程完全攻略 - 扩展 - 可被关闭的线程类
本文假设读者已经基本了解boost线程库的使用方法. boost是个开源工程,线程这一块也在不断完善之中,到现在这个阶段,boost::thread仅仅实现了一个完美的技术框架,但是读者在实际使用中会 ...
- BOOST 线程完全攻略 - 扩展 - 事务线程
扩展threadtimermoduleexceptionsocket 什么叫事务线程 举个例子: 我们写一个IM客户端的登录子线程,则该子线程会有这么几个事务要处理 No.1 TCP Socket物理 ...
- BOOST 线程完全攻略 - 结束语
modulethread扩展多线程破解通讯 全文介绍了3个boost::thread的扩展类,希望能给大家书写多线程代码带来便捷. thread -> controlled_module_ex ...
- BOOST 线程完全攻略 - 基础篇
http://blog.csdn.net/iamnieo/article/details/2908621 2008-09-10 12:48 9202人阅读 评论(3) 收藏 举报 thread多线程l ...
- BOOST 线程完全攻略
1 创建线程 首先看看boost::thread的构造函数吧,boost::thread有两个构造函数: (1)thread():构造一个表示当前执行线程的线程对象: (2)explicit thre ...
- 【C/C++】BOOST 线程完全攻略 - 基础篇
C++多线程开发是一个复杂的事情,mfc下提供了CWinThread类,和AfxBeginThread等等函数,但是在使用中会遇到很多麻烦事情,例如线程之间参数传递的问题,我们一般都是把参数new一个 ...
- VCL线程的同步方法 Synchronize(用消息来同步)
看本文时,可以同时参考:Delphi中线程类 TThread实现多线程编程(事件.临界区.Synchronize.WaitFor……) 先说一下RTL和VCL RTL(Run-Time library ...
- boost中asio网络库多线程并发处理实现,以及asio在多线程模型中线程的调度情况和线程安全。
1.实现多线程方法: 其实就是多个线程同时调用io_service::run for (int i = 0; i != m_nThreads; ++i) { boo ...
- Chrome插件(扩展)开发全攻略
[干货]Chrome插件(扩展)开发全攻略:https://www.cnblogs.com/liuxianan/p/chrome-plugin-develop.html
随机推荐
- 黑马程序员—— Java SE(3)
----<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训 ...
- 多余的Using Namespaces或引用会影响程序的执行效率么?(转)
转自:http://www.cnblogs.com/Interkey/p/UsingNameSpace.html 多余的Using Namespaces或引用会影响程序的执行效率么? 在.NET程序编 ...
- (转) 值不能为空。参数名viewinfo(microsoft.sqlserver.management.sqlstudio.explorer)
打开MSSQL 2008 R2的时候,展开数据库都显示以下的错误提示: 值不能为空.参数名viewinfo(microsoft.sqlserver.management.sqlstudio.explo ...
- C# 程序打包
1:新建安装部署项目打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装项目,然后点击确定.(详细见下图) 此主题相关图片如下: 2:开始打包2.1 确定即可进入项目文件夹:双 ...
- c#鼠标在控件上面,然后显示文字
先添加toolTip控件到界面 然后每个控件的属性会多一项 ToolTip 第一种:直接给里面加文字 第二种: private void pictureBox_topmost_MouseHover(o ...
- Handlebars expressions
Basic Usage 1,最简单的handlebars 表达式 <h1>{{title}}</h1> 使用时,会在当前context里找名为title的property,替换 ...
- POJ2239 二分图最大匹配
问题:POJ2239 分析: 本题给出每门课程的上课时间,求最大选课数,可以转化为二分图最大匹配问题求解. 设集合A为课程集,集合B为上课时间集,根据输入建立二分图.最大选课书就是该二分图的最大匹配数 ...
- Netbeans7.4下搭建struts2.3.16
一:所需要的jar包如下: 在WEB-INF目录下新建一个lib文件夹将jar包复制到里面: 在这里要注意将jar包导入lib目录里还不可以,在这里与MyEclipse不同.在项目上右键属性-> ...
- 《Programming WPF》翻译 第5章 6.触发器
原文:<Programming WPF>翻译 第5章 6.触发器 目前为止,我们已经看到样式,作为一个Setter元素的集合.当应用一个样式时,在Setter元素中描述的设置不会无条件地应 ...
- 一键安装IIS的点点滴滴——For所有Microsoft的操作系统(上)
原文www.cnblogs.com/cdts_change/archive/2010/03/04/1677338.html 临近公司的软件要完工了,最近几天一直在泉哥的带领下为我们公司的产品做IIS一 ...