usidc5 | 2011-10-28 20:44 | 本文假设读者已经基本了解boost线程库的使用方法。
boost是个开源工程,线程这一块也在不断完善之中,到现在这个阶段,boost::thread仅仅实现了一个完美的技术框架,但是读者在实际使用中会发现一些新的技术问题:
1.boost::thread::join开启一个线程以后,怎样主动结束子线程?
2.boost线程之间怎样实现消息传递?
作者在这里描述怎样一步步扩展这些功能。
一. Janitor 异常安全处理
本文的janitor.hpp是针对异常安全处理的封装类,在后面的扩展类里面有使用到,异常安全的目的是为了保证程序的一段事务的完整性,关于异常安全不是本文的重点,感兴趣的话可以参见http://dev.csdn/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()函数,直到线程退出
| |
发表评论