BOOST 线程完全攻略 - 扩展 - 可被关闭的线程类

本文假设读者已经基本了解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()函数,直到线程退出

你可能感兴趣的:(BOOST 线程完全攻略 - 扩展 - 可被关闭的线程类)