转自:http://blog.csdn.net/IamNieo/archive/2008/09/10/2909236.aspx
-
- #pragmaonce
- #include<boost/shared_ptr.hpp>
- #include<boost/any.hpp>
- #include"controlled_module.hpp"
-
-
struct_command
- {
-
typedefboost::shared_ptr<_command>CCmdPtr;
-
unsignedintnCmd;
- boost::anyanyParam;
- };
-
struct_wait_command
- {
- boost::anypar;
-
unsignedintcommand;
-
void*event;
- boost::shared_ptr<boost::any>resp;
- };
-
classcontrolled_module_ex;
-
struct_notify
- {
- controlled_module_ex*sender;
-
intid;
- boost::anypar;
- };
- #defineBM_RESERVE1000
- #defineBM_RING_STARTBM_RESERVE+1
- #defineBM_RING_STOPBM_RESERVE+2
- #defineBM_RING_SETTIMEBM_RESERVE+3
- #defineBM_RING_SETPARENTBM_RESERVE+4
- #defineBM_RING_CYCLEBM_RESERVE+5
- #defineBM_RING_PROCESSBM_RESERVE+6
- #defineBM_RING_PROCESSENDBM_RESERVE+7
- #defineBM_RING_PROCESSFAILBM_RESERVE+8
- #defineBM_TIMERBM_RESERVE+9
- #defineBM_COMMANDBM_RESERVE+10
- #defineBM_NOTIFYBM_RESERVE+11
-
- #defineBM_USER9000
-
classcontrolled_timer;
-
classcontrolled_module_ex:publiccontrolled_module
- {
-
public:
- controlled_module_ex()
- {
-
m_safe=false;
- }
- ~controlled_module_ex()
- {
- safestop();
- }
-
public:
-
template<typenameT>
-
boolpostmessage(unsignedintnCmd,constboost::shared_ptr<T>&p)
- {
-
if(this==0||!m_safe)returnfalse;
- boost::mutex::scoped_locklock(m_mutex_command);
-
_command::CCmdPtrcmd(new_command);
- cmd->nCmd=nCmd;
- cmd->anyParam=p;
- m_list_command.push_back(cmd);
-
returntrue;
- }
-
boost::anyexecute(unsignedintcommand,boost::anypar,inttimeout=-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>(newboost::any);
-
if(this->postmessage(BM_COMMAND,shared))
- {
-
DWORDdw=WaitForSingleObject(cmd.event,timeout);
- CloseHandle(cmd.event);
-
if(dw!=WAIT_OBJECT_0)
-
returnboost::any();
-
else
-
return*cmd.resp;
- }
-
else
- {
- CloseHandle(cmd.event);
-
returnboost::any();
- }
- }
-
voidnotify(_notifyp)
- {
-
this->postmessage(BM_NOTIFY,p);
- }
-
boolpostmessage(unsignedintnCmd,boost::anyp)
- {
-
if(this==0||!m_safe)
-
returnfalse;
- boost::mutex::scoped_locklock(m_mutex_command);
-
_command::CCmdPtrcmd(new_command);
- cmd->nCmd=nCmd;
- cmd->anyParam=p;
- m_list_command.push_back(cmd);
-
returntrue;
- }
-
boolpostmessage(unsignedintnCmd)
- {
-
if(this==0||!m_safe)
-
returnfalse;
- boost::mutex::scoped_locklock(m_mutex_command);
-
_command::CCmdPtrcmd(new_command);
- cmd->nCmd=nCmd;
- cmd->anyParam=0;
- m_list_command.push_back(cmd);
-
returntrue;
- }
-
virtualboolwork()
- {
-
if(!getmessage())
-
returnfalse;
-
else
- {
-
Sleep(this->m_sleeptime);
-
returntrue;
- }
- }
-
virtualvoidmessage(const_command&cmd)
- {
-
if(cmd.nCmd==BM_RING_START)
- {
-
this->on_safestart();
- }
-
elseif(cmd.nCmd==BM_RING_STOP)
- {
-
this->on_safestop();
- }
-
elseif(cmd.nCmd==BM_TIMER)
- {
-
this->on_timer(boost::any_cast<controlled_timer*>(cmd.anyParam));
- }
-
elseif(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);
- }
-
elseif(cmd.nCmd==BM_NOTIFY)
- {
-
try
- {
- _notifypar=boost::any_cast<_notify>(cmd.anyParam);
-
this->on_notify(par);
- }
-
catch(boost::bad_any_cast)
- {
- }
- }
- }
-
virtualvoidrelease()
- {
- boost::mutex::scoped_locklock(m_mutex_command);
- m_list_command.clear();
- }
-
voidsafestart()
- {
-
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);
- }
-
voidsafestop()
- {
-
if(this->islive())
- {
-
m_safe=false;
-
m_safestop_event=(void*)CreateEvent(NULL,FALSE,FALSE,0);
- {
- boost::mutex::scoped_locklock(m_mutex_command);
-
_command::CCmdPtrcmd(new_command);
- cmd->nCmd=BM_RING_STOP;
- cmd->anyParam=0;
- m_list_command.push_back(cmd);
- }
-
DWORDdw=::WaitForSingleObject((HANDLE)m_safestop_event,3*1000);
-
if(WAIT_OBJECT_0!=dw)
- {
- }
- CloseHandle(m_safestop_event);
- stop();
- }
- }
-
virtualvoidon_timer(constcontrolled_timer*p){}
-
virtualvoidon_safestart()
- {
- SetEvent(m_safestart_event);
- }
-
virtualvoidon_safestop()
- {
- SetEvent(m_safestop_event);
- }
-
virtualvoidon_notify(const_notify&p)
- {
- }
-
protected:
-
virtualboost::anyon_command(constunsignedintcommand,constboost::anypar)
- {
-
returnboost::any();
- }
-
boolgetmessage()
- {
- std::list<_command::CCmdPtr>cache;
- {
- boost::mutex::scoped_locklock(m_mutex_command);
-
while(!m_list_command.empty())
- {
- _command::CCmdPtrp=m_list_command.front();
- m_list_command.pop_front();
- cache.push_back(p);
- }
- }
- _command::CCmdPtrstop_command;
- std::list<_command::CCmdPtr>::iteratoritem;
-
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::CCmdPtrp=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&)
- {
- }
- }
-
returntrue;
- }
-
else
- {
- cache.clear();
-
this->message(*stop_command);
-
returnfalse;
- }
- }
-
private:
-
void*m_safestart_event;
-
void*m_safestop_event;
-
boolm_safe;
- boost::mutexm_mutex_command;
- std::list<_command::CCmdPtr>m_list_command;
- };
-
classcontrolled_timer:publiccontrolled_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;
-
intm_time;
-
intm_step;
-
public:
-
voidstarttimer(inttime,controlled_module_ex*parent)
- {
-
this->safestart();
-
this->postmessage(BM_RING_SETPARENT,parent);
-
this->postmessage(BM_RING_SETTIME,time);
- }
-
voidstoptimer()
- {
-
this->safestop();
- }
-
public:
-
virtualvoidon_safestop()
- {
- m_time=0;
- controlled_module_ex::on_safestop();
- }
-
virtualvoidmessage(const_command&cmd)
- {
- controlled_module_ex::message(cmd);
-
if(cmd.nCmd==BM_RING_SETTIME)
- {
-
inttime=boost::any_cast<int>(cmd.anyParam);
-
this->m_time=time/this->m_sleeptime;
-
this->postmessage(BM_RING_CYCLE);
- }
-
elseif(cmd.nCmd==BM_RING_SETPARENT)
- {
-
this->m_parent=boost::any_cast<controlled_module_ex*>(cmd.anyParam);
- }
-
elseif(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
函数controlled_module_ex::postmessage完成消息推送。
虚拟函数controlled_module_ex::message(const _command & cmd)实现消息接收。
- #include"controlled_module_ex.hpp"
-
-
-
classthdex:publiccontrolled_module_ex
- {
-
protected:
-
virtualvoidmessage(const_command&cmd)
- {
- controlled_module_ex::message(cmd);
-
if(cmd.nCmd==BM_USER+1)
- {
-
cout<<"getmessage"<<endl;
- }
- }
- };
-
-
int_tmain(intargc,_TCHAR*argv[])
- {
- thdext;
- t.safestart();
- t.postmessage(BM_USER+1);
-
charbuf[10];
-
gets_s(buf,sizeofbuf);
- t.safestop();
-
return0;
- }
2.向线程PostMessage,并携带简单对象参数
我们都知道常规的PostMessage要传参,如果是整型参数,还可以用强制转换,但如果是其他类型,例如字符串,我们就必须创建一个字符串缓冲,把缓冲指针作为参数传过去,线程还不能忘记删除,否则导致内存泄漏,自定义结构也是一样的操作,如果想尝试传递一个CString对象,是不可能的。
幸运的是boost提供了boost::any来抽象任何对象类型,controlled_module_ex的消息传递都是基于boost::any来完成,程序员可以由此写出干净而且内存安全的代码。
- #include"controlled_module_ex.hpp"
-
-
structmystruct
- {
- stringa;
-
intb;
- };
-
classthdex:publiccontrolled_module_ex
- {
-
protected:
-
virtualvoidmessage(const_command&cmd)
- {
- controlled_module_ex::message(cmd);
-
if(cmd.nCmd==BM_USER+1)
- {
-
cout<<"getinteger:"<<boost::any_cast<int>(cmd.anyParam)<<endl;
- }
-
if(cmd.nCmd==BM_USER+2)
- {
-
cout<<"getstring:"<<boost::any_cast<string>(cmd.anyParam)<<endl;
- }
-
if(cmd.nCmd==BM_USER+3)
- {
- mystructpar=boost::any_cast<mystruct>(cmd.anyParam);
-
cout<<"getmystruct:"<<par.a<<","<<par.b<<endl;
- }
- }
- };
-
-
int_tmain(intargc,_TCHAR*argv[])
- {
- thdext;
- t.safestart();
- t.postmessage(BM_USER+1,123);
-
t.postmessage(BM_USER+2,string("helloworld"));
- mystructpar;
-
par.a="helloworld";
- par.b=123;
- t.postmessage(BM_USER+3,par);
-
-
charbuf[10];
-
gets_s(buf,sizeofbuf);
- t.safestop();
-
return0;
- }
-
-
3.向线程PostMessage,并传递内存块参数
假如我们书写了一个录音子线程,如何将录制的语音数据传递给其他线程呢,常规做法是创建一个缓冲,将语音数据填充进去,然后将缓冲地址作为参数传递,这种做法要求接收线程不能忘记删除,否则会导致内存泄漏。
幸运的是boost提供了智能指针,可以类似java,c#的智能内存回收一样来管理内存分配,我们如果使用这个对象来作为参数传递,就可以完美的防范内存泄漏行为,就算子线程没有处理,别担心,内存它会自动回收的。
- #include"controlled_module_ex.hpp"
-
-
structmystruct
- {
-
boost::shared_ptr<char>data;
-
intdatalen;
- };
-
classthdex:publiccontrolled_module_ex
- {
-
protected:
-
virtualvoidmessage(const_command&cmd)
- {
- controlled_module_ex::message(cmd);
-
if(cmd.nCmd==BM_USER+1)
- {
-
cout<<"getsharedptr"<<endl;
- }
-
if(cmd.nCmd==BM_USER+2)
- {
- mystructpar=boost::any_cast<mystruct>(cmd.anyParam);
-
cout<<"getsharedptrlen:"<<par.datalen<<endl;
- }
- }
- };
-
-
int_tmain(intargc,_TCHAR*argv[])
- {
- thdext;
- t.safestart();
-
t.postmessage(BM_USER+1,boost::shared_ptr<char>(newchar[1000]));
- mystructpar;
- par.datalen=1000;
-
par.data=boost::shared_ptr<char>(newchar[par.datalen]);
- t.postmessage(BM_USER+2,par);
-
-
charbuf[10];
-
gets_s(buf,sizeofbuf);
- t.safestop();
-
return0;
- }
-
-
3.向线程SendMessage
函数controlled_module_ex::execute完成这个工作
虚拟函数controlled_module_ex::on_command(const unsigned int command,const boost::any par)响应消息处理
- #include"controlled_module_ex.hpp"
-
-
classthdex:publiccontrolled_module_ex
- {
-
protected:
-
boost::anyon_command(constunsignedintcommand,constboost::anypar)
- {
-
if(command==1)
- {
-
cout<<"oncommand"<<endl;
-
return0;
- }
-
if(command==2)
- {
-
cout<<"oncommand,par:"<<boost::any_cast<string>(par)<<endl;
-
return0;
- }
-
if(command==3)
- {
-
returntrue;
- }
-
else
-
returncontrolled_module_ex::on_command(command,par);
- }
- };
-
-
int_tmain(intargc,_TCHAR*argv[])
- {
- thdext;
- t.safestart();
-
t.execute(1,0);
-
t.execute(2,string("helloworld"));
-
boolrs=boost::any_cast<bool>(t.execute(3,0));
-
cout<<"getthreadresult:"<<rs<<endl;
-
boost::anytimeout=t.execute(4,0,1000);
-
if(timeout.empty())
-
cout<<"timeout"<<endl;
-
-
charbuf[10];
-
gets_s(buf,sizeofbuf);
- t.safestop();
-
return0;
- }
4.定时器
类似于CWnd::OnTimer,controlled_module_ex也提供一个虚拟函数virtual void on_timer(const controlled_timer * p);来处理定时
- #include"controlled_module_ex.hpp"
-
-
classthdex:publiccontrolled_module_ex
- {
-
protected:
-
virtualvoidon_timer(constcontrolled_timer*p)
- {
-
cout<<"ontimer"<<endl;
- }
- };
-
-
int_tmain(intargc,_TCHAR*argv[])
- {
- thdext;
- controlled_timertimer;
- t.safestart();
- timer.starttimer(1000,&t);
-
-
charbuf[10];
-
gets_s(buf,sizeofbuf);
- t.safestop();
-
return0;
- }
分享到:
相关推荐
boost159-locale-1.59.0-2.el7.x86_64.rpm
boost159-openmpi-python-1.59.0-2.el7.1.x86_64.rpm
boost159-filesystem-1.59.0-2.el7.x86_64.rpm
boost159-regex-1.59.0-2.el7.1.x86_64.rpm
matlab 2014b 破解缺少dll,boost_date_time-vc100-mt-1_49.dll,以及boost_filesystem-vc100-mt-1_49.dll
boost代码----------
boost159-1.59.0-2.el7.x86_64.rpm
boost线程指南手册。Boost 1.35.0的中文版。
boost159-program-options-1.59.0-2.el7.x86_64.rpm
boost----mysql connector c++ for visual studio 2008
boost159-atomic-1.59.0-2.el7.x86_64.rpm
基于Buck_Boost的AC--AC变换器设计方案pdf,基于BuckBoost的ACAC变换器设计.pdf
《xapp1206-boost-sw-performance-zynq7soc-w-neon.pdf》 xilinx开发手册,指导手册.官方文档
matlab 2016a 由于找不到 boost_iostreams-vc120-mt-1_56.dll,无法继续执行代码。重新安装程序可能会解决此问题。
离线安装包,亲测可用
boost159-build-1.59.0-2.el7.noarch.rpm
boost159-filesystem-1.59.0-2.el7.1.x86_64.rpm
离线安装包,测试可用
boost_date_time-vc100-mt-1_49.dll
离线安装包,亲测可用