本文假设读者已经基本了解boost线程库的使用方法。 boost是个开源工程,线程这一块也在不断完善之中,到现在这个阶段,boost::thread仅仅实现了一个完美的技术框架,但是读者在实际使用中会发现一些新的技术问题: 1.boost::thread::join开启一个线程以后,怎样主动结束子线程? 2.boost线程之间怎样实现消息传递? 作者在这里描述怎样一步步扩展这些功能。 一. Janitor 异常安全处理 本文的janitor.hpp是针对异常安全处理的封装类,在后面的扩展类里面有使用到,异常安全的目的是为了保证程序的一段事务的完整性,关于异常安全不是本文的重点,感兴趣的话可以参见http://dev.csdn.net/article/6/6883.shtm // janitor.hpp : 安全执行类库 // #pragma once #include <list> template <class T> class RefHolder { T& ref_; public: RefHolder(T& ref) : ref_(ref) {} operator T& () const { return ref_; } private: // Disable assignment - not implemented RefHolder& operator=(const RefHolder&); }; template <class T> inline RefHolder<T> ByRef(T& t) { return RefHolder<T>(t); } class ScopeGuardImplBase { ScopeGuardImplBase& operator =(const ScopeGuardImplBase&); protected: ~ScopeGuardImplBase() { } ScopeGuardImplBase(const ScopeGuardImplBase& other) throw() : dismissed_(other.dismissed_) { other.Dismiss(); } template <typename J> static void SafeExecute(J& j) throw() { if (!j.dismissed_) try { j.Execute(); } catch(...) { } } mutable bool dismissed_; public: ScopeGuardImplBase() throw() : dismissed_(false) { } void Dismiss() const throw() { dismissed_ = true; } }; typedef const ScopeGuardImplBase& ScopeGuard; template <typename F> class ScopeGuardImpl0 : public ScopeGuardImplBase { public: static ScopeGuardImpl0<F> MakeGuard(F fun) { return ScopeGuardImpl0<F>(fun); } ~ScopeGuardImpl0() throw() { SafeExecute(*this); } void Execute() { fun_(); } protected: ScopeGuardImpl0(F fun) : fun_(fun) { } F fun_; }; template <typename F> inline ScopeGuardImpl0<F> MakeGuard(F fun) { return ScopeGuardImpl0<F>::MakeGuard(fun); } template <typename F, typename P1> class ScopeGuardImpl1 : public ScopeGuardImplBase { public: static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) { return ScopeGuardImpl1<F, P1>(fun, p1); } ~ScopeGuardImpl1() throw() { SafeExecute(*this); } void Execute() { fun_(p1_); } protected: ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1) { } F fun_; const P1 p1_; }; template <typename F, typename P1> inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) { return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1); } template <typename F, typename P1, typename P2> class ScopeGuardImpl2: public ScopeGuardImplBase { public: static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2) { return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2); } ~ScopeGuardImpl2() throw() { SafeExecute(*this); } void Execute() { fun_(p1_, p2_); } protected: ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2) { } F fun_; const P1 p1_; const P2 p2_; }; template <typename F, typename P1, typename P2> inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2) { return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2); } template <typename F, typename P1, typename P2, typename P3> class ScopeGuardImpl3 : public ScopeGuardImplBase { public: static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3) { return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3); } ~ScopeGuardImpl3() throw() { SafeExecute(*this); } void Execute() { fun_(p1_, p2_, p3_); } protected: ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3) { } F fun_; const P1 p1_; const P2 p2_; const P3 p3_; }; template <typename F, typename P1, typename P2, typename P3> inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3) { return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3); } //************************************************************ template <class Obj, typename MemFun> class ObjScopeGuardImpl0 : public ScopeGuardImplBase { public: static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun) { return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun); } ~ObjScopeGuardImpl0() throw() { SafeExecute(*this); } void Execute() { (obj_.*memFun_)(); } protected: ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun) {} Obj& obj_; MemFun memFun_; }; template <class Obj, typename MemFun> inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun) { return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun); } template <class Obj, typename MemFun, typename P1> class ObjScopeGuardImpl1 : public ScopeGuardImplBase { public: static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1) { return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1); } ~ObjScopeGuardImpl1() throw() { SafeExecute(*this); } void Execute() { (obj_.*memFun_)(p1_); } protected: ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1) {} Obj& obj_; MemFun memFun_; const P1 p1_; }; template <class Obj, typename MemFun, typename P1> inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1) { return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1); } template <class Obj, typename MemFun, typename P1, typename P2> class ObjScopeGuardImpl2 : public ScopeGuardImplBase { public: static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2) { return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2); } ~ObjScopeGuardImpl2() throw() { SafeExecute(*this); } void Execute() { (obj_.*memFun_)(p1_, p2_); } protected: ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) {} Obj& obj_; MemFun memFun_; const P1 p1_; const P2 p2_; }; template <class Obj, typename MemFun, typename P1, typename P2> inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2) { return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2); } #define CONCATENATE_DIRECT(s1, s2) s1##s2 #define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2) #define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__) #define ON_BLOCK_EXIT ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard #define ON_BLOCK_EXIT_OBJ ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard ////////////////////////////////////////////////////////////////////////////////////////// // janitor struct ICmd_ { virtual void Dismiss() const throw() = 0; virtual ~ICmd_() throw() {} }; template<typename T> class CmdAdaptor : public ICmd_, protected T { public: template<typename Fun> CmdAdaptor(Fun fun) : T(fun) {} template<typename Fun, typename P1> CmdAdaptor(Fun fun, P1 p1) : T(fun, p1) {} template<typename Fun, typename P1, typename P2> CmdAdaptor(Fun fun, P1 p1, P2 p2) : T(fun, p1, p2) {} template<typename Fun, typename P1, typename P2, typename P3> CmdAdaptor(Fun fun, P1 p1, P2 p2, P3 p3) : T(fun, p1, p2, p3) {} void Dismiss() const throw() { T::Dismiss(); } }; class Janitor { public: Janitor() throw() {} template <typename F> Janitor(F pFun) : spCmd_( new CmdAdaptor<ScopeGuardImpl0<F> >(pFun)) {} template <typename F, typename P1> Janitor(F pFun, P1 p1) : spCmd_( new CmdAdaptor<ScopeGuardImpl1<F, P1> >(pFun, p1)) {} template <typename F, typename P1, typename P2> Janitor(F pFun, P1 p1, P2 p2) : spCmd_( new CmdAdaptor<ScopeGuardImpl2<F, P1, P2> >(pFun, p1, p2)) {} template <typename F, typename P1, typename P2, typename P3> Janitor(F pFun, P1 p1, P2 p2, P3 p3) : spCmd_( new CmdAdaptor<ScopeGuardImpl3<F, P1, P2, P3> >(pFun, p1, p2, p3)) {} Janitor(const Janitor& other) throw() : spCmd_(other.spCmd_) {} //VC++, Comeau need it! Janitor& operator =(const Janitor& other) throw() { if (spCmd_.get()) spCmd_->Dismiss(); spCmd_ = other.spCmd_; return *this; } void Dismiss() const throw() { spCmd_->Dismiss(); } protected: mutable std::auto_ptr<ICmd_> spCmd_; }; template<typename T> class ObjCmdAdaptor : public ICmd_, protected T { public: template<typename Obj, typename MemFun> ObjCmdAdaptor(Obj& obj, MemFun memFun) : T(obj, memFun) {} template<typename Obj, typename MemFun, typename P1> ObjCmdAdaptor(Obj& obj, MemFun memFun, P1 p1) : T(obj, memFun, p1) {} template<typename Obj, typename MemFun, typename P1, typename P2> ObjCmdAdaptor(Obj& obj, MemFun memFun, P1 p1, P2 p2) : T(obj, memFun, p1, p2) {} void Dismiss() const throw() { T::Dismiss(); } }; class ObjJanitor : protected Janitor { public: using Janitor::Dismiss; ObjJanitor() throw() {} template <typename Obj, typename MemFun> ObjJanitor(Obj& obj, MemFun memFun) { std::auto_ptr<ICmd_> spTmp( new ObjCmdAdaptor<ObjScopeGuardImpl0<Obj, MemFun> >(obj, memFun)); spCmd_ = spTmp; } template <typename Obj, typename MemFun, typename P1> ObjJanitor(Obj& obj, MemFun memFun, P1 p1) { std::auto_ptr<ICmd_> spTmp( new ObjCmdAdaptor<ObjScopeGuardImpl1<Obj, MemFun, P1> >(obj, memFun, p1)); spCmd_ = spTmp; } template <typename Obj, typename MemFun, typename P1, typename P2> ObjJanitor(Obj& obj, MemFun memFun, P1 p1, P2 p2) { std::auto_ptr<ICmd_> spTmp( new ObjCmdAdaptor<ObjScopeGuardImpl2<Obj, MemFun, P1, P2> >(obj, memFun, p1, p2)); spCmd_ = spTmp; } }; 使用范例 #include "stdafx.h" #include <iostream> #include <string> using namespace std; #include "janitor.hpp" class class1 { public: class1() { } ~class1() { } public: void test() { ObjJanitor ja(*this,&class1::testJanitor); } void testJanitor() { cout << "hello world" << endl; } }; int _tmain(int argc, _TCHAR* argv[]) { class1 c; c.test(); return 0; } 二.controlled_module 可被关闭的线程类 该类原型来自于一个叫“阿修罗”的原始类 // controlled_module.hpp : 可主动关闭的boost线程类 // #pragma once #include <boost/utility.hpp> #include <boost/thread/condition.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/thread.hpp> #include <boost/bind.hpp> #include "janitor.hpp" class controlled_module_implement : boost::noncopyable { public: controlled_module_implement() :active_(false),command_exit_(false){} boost::condition module_is_exit; boost::mutex monitor; void active(bool ac) {boost::mutex::scoped_lock lk(monitor); if(!(active_=ac))module_is_exit.notify_all();else command_exit_=false;} bool command_exit(){boost::mutex::scoped_lock lk(monitor); return command_exit_;} bool active_,command_exit_; }; class controlled_module : boost::noncopyable { public: virtual void run() { ObjJanitor janitor(*impl_,&controlled_module_implement::active,false); impl_->active(true); { ObjJanitor janitor(*this,&controlled_module::release); if(this->initialize()) { m_live = true; SetEvent(m_event_init); while(!impl_->command_exit() && this->islive() && this->work()) { } } else { m_live = false; SetEvent(m_event_init); } } } bool exit(unsigned long sec=0) { boost::mutex::scoped_lock lk(impl_->monitor); impl_->command_exit_ = true; while(impl_->active_) { if(sec) { boost::xtime xt; boost::xtime_get(&xt, boost::TIME_UTC); xt.sec += sec; if(!impl_->module_is_exit.timed_wait(lk,xt)) return false; } else impl_->module_is_exit.wait(lk); } return true; } protected: controlled_module() :impl_(new controlled_module_implement) ,m_live(false) ,m_event_init(0) ,m_sleeptime(10) { } virtual ~controlled_module() { if(m_live) stop(); delete impl_; } private: virtual bool initialize(){return true;} virtual void release(){} protected: virtual bool work() { Sleep(this->m_sleeptime); return true; } int m_sleeptime; private: bool m_live; void * m_event_init; controlled_module_implement* impl_; public: bool start() { m_event_init = CreateEvent(NULL,FALSE,FALSE,""); boost::thread thd(boost::bind(&controlled_module::run,this)); ::WaitForSingleObject(m_event_init,INFINITE); CloseHandle(m_event_init); m_event_init = 0; return m_live; } void stop() { m_live = false; exit(1); } bool islive(){return m_live;} void die() { m_live = false; SetEvent(m_event_init); } void setsleeptime(int n) { m_sleeptime = n; } }; virtual bool initialize(); 初始化 virtual void release(); 释放 virtual bool work(); 工作函数 如果我们要创建一个可被关闭的线程,可以如下步骤: 1)创建一个controlled_module 继承类 2)实现3个虚拟函数 3)用start(),stop()启动和停止线程 范例: //controlled_module demo #include "controlled_module.hpp" class thd: public controlled_module { public: virtual bool initialize() { cout << "thd init" << endl; return true; } virtual void release() { cout << "thd release" << endl; } virtual bool work() { //your work........ return controlled_module::work(); } }; int _tmain(int argc, _TCHAR* argv[]) { thd t; t.start(); char buf[10]; gets_s(buf,sizeof buf); t.stop(); return 0; } thd线程在启动以后,将循环执行work()函数,直到线程退出