Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1885085
  • 博文数量: 496
  • 博客积分: 12043
  • 博客等级: 上将
  • 技术积分: 4778
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-27 14:26
文章分类

全部博文(496)

文章存档

2014年(8)

2013年(4)

2012年(181)

2011年(303)

2010年(3)

分类: C/C++

2011-12-06 14:35:28

本文假设读者已经基本了解boost线程库的使用方法。

boost是个开源工程,线程这一块也在不断完善之中,到现在这个阶段,boost::thread仅仅实现了一个完美的技术框架,但是读者在实际使用中会发现一些新的技术问题:
1.boost::thread::join开启一个线程以后,怎样主动结束子线程?
2.boost线程之间怎样实现消息传递?
作者在这里描述怎样一步步扩展这些功能。
一. Janitor 异常安全处理
  本文的janitor.hpp是针对异常安全处理的封装类,在后面的扩展类里面有使用到,异常安全的目的是为了保证程序的一段事务的完整性,关于异常安全不是本文的重点,感兴趣的话可以参见http://dev.csdn.net/article/6/6883.shtm
  1. // janitor.hpp : 安全执行类库
  2. //
  3. #pragma once
  4. #include 
  5. template <class T>
  6. class RefHolder
  7. {
  8.         T& ref_;
  9. public:
  10.         RefHolder(T& ref) : ref_(ref) {}
  11.         operator T& () const 
  12.         {
  13.                 return ref_;
  14.         }
  15. private:
  16.     // Disable assignment - not implemented
  17.     RefHolder& operator=(const RefHolder&);
  18. };

  19. template <class T>
  20. inline RefHolder ByRef(T& t)
  21. {
  22.         return RefHolder(t);
  23. }

  24. class ScopeGuardImplBase
  25. {
  26.         ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
  27. protected:
  28.         ~ScopeGuardImplBase()
  29.         {
  30.         }
  31.         ScopeGuardImplBase(const ScopeGuardImplBase& other) throw() 
  32.                 : dismissed_(other.dismissed_)
  33.         {
  34.                 other.Dismiss();
  35.         }
  36.         template <typename J>
  37.         static void SafeExecute(J& j) throw() 
  38.         {
  39.                 if (!j.dismissed_)
  40.                         try
  41.                         {
  42.                                 j.Execute();
  43.                         }
  44.                         catch(...)
  45.                         {
  46.                         }
  47.         }
  48.         
  49.         mutable bool dismissed_;
  50. public:
  51.         ScopeGuardImplBase() throw() : dismissed_(false
  52.         {
  53.         }
  54.         void Dismiss() const throw() 
  55.         {
  56.                 dismissed_ = true;
  57.         }
  58. };

  59. typedef const ScopeGuardImplBase& ScopeGuard;

  60. template <typename F>
  61. class ScopeGuardImpl0 : public ScopeGuardImplBase
  62. {
  63. public:
  64.         static ScopeGuardImpl0 MakeGuard(F fun)
  65.         {
  66.                 return ScopeGuardImpl0(fun);
  67.         }
  68.         ~ScopeGuardImpl0() throw() 
  69.         {
  70.                 SafeExecute(*this);
  71.         }
  72.         void Execute() 
  73.         {
  74.                 fun_();
  75.         }
  76. protected:
  77.         ScopeGuardImpl0(F fun) : fun_(fun) 
  78.         {
  79.         }
  80.         F fun_;
  81. };

  82. template <typename F> 
  83. inline ScopeGuardImpl0 MakeGuard(F fun)
  84. {
  85.         return ScopeGuardImpl0::MakeGuard(fun);
  86. }

  87. template <typename F, typename P1>
  88. class ScopeGuardImpl1 : public ScopeGuardImplBase
  89. {
  90. public:
  91.         static ScopeGuardImpl1 MakeGuard(F fun, P1 p1)
  92.         {
  93.                 return ScopeGuardImpl1(fun, p1);
  94.         }
  95.         ~ScopeGuardImpl1() throw() 
  96.         {
  97.                 SafeExecute(*this);
  98.         }
  99.         void Execute()
  100.         {
  101.                 fun_(p1_);
  102.         }
  103. protected:
  104.         ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1) 
  105.         {
  106.         }
  107.         F fun_;
  108.         const P1 p1_;
  109. };

  110. template <typename F, typename P1> 
  111. inline ScopeGuardImpl1 MakeGuard(F fun, P1 p1)
  112. {
  113.         return ScopeGuardImpl1::MakeGuard(fun, p1);
  114. }

  115. template <typename F, typename P1, typename P2>
  116. class ScopeGuardImpl2: public ScopeGuardImplBase
  117. {
  118. public:
  119.         static ScopeGuardImpl2 MakeGuard(F fun, P1 p1, P2 p2)
  120.         {
  121.                 return ScopeGuardImpl2(fun, p1, p2);
  122.         }
  123.         ~ScopeGuardImpl2() throw() 
  124.         {
  125.                 SafeExecute(*this);
  126.         }
  127.         void Execute()
  128.         {
  129.                 fun_(p1_, p2_);
  130.         }
  131. protected:
  132.         ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2) 
  133.         {
  134.         }
  135.         F fun_;
  136.         const P1 p1_;
  137.         const P2 p2_;
  138. };

  139. template <typename F, typename P1, typename P2>
  140. inline ScopeGuardImpl2 MakeGuard(F fun, P1 p1, P2 p2)
  141. {
  142.         return ScopeGuardImpl2::MakeGuard(fun, p1, p2);
  143. }

  144. template <typename F, typename P1, typename P2, typename P3>
  145. class ScopeGuardImpl3 : public ScopeGuardImplBase
  146. {
  147. public:
  148.         static ScopeGuardImpl3 MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
  149.         {
  150.                 return ScopeGuardImpl3(fun, p1, p2, p3);
  151.         }
  152.         ~ScopeGuardImpl3() throw() 
  153.         {
  154.                 SafeExecute(*this);
  155.         }
  156.         void Execute()
  157.         {
  158.                 fun_(p1_, p2_, p3_);
  159.         }
  160. protected:
  161.         ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3) 
  162.         {
  163.         }
  164.         F fun_;
  165.         const P1 p1_;
  166.         const P2 p2_;
  167.         const P3 p3_;
  168. };

  169. template <typename F, typename P1, typename P2, typename P3>
  170. inline ScopeGuardImpl3 MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
  171. {
  172.         return ScopeGuardImpl3::MakeGuard(fun, p1, p2, p3);
  173. }

  174. //************************************************************

  175. template <class Obj, typename MemFun>
  176. class ObjScopeGuardImpl0 : public ScopeGuardImplBase
  177. {
  178. public:
  179.         static ObjScopeGuardImpl0 MakeObjGuard(Obj& obj, MemFun memFun)
  180.         {
  181.                 return ObjScopeGuardImpl0(obj, memFun);
  182.         }
  183.         ~ObjScopeGuardImpl0() throw() 
  184.         {
  185.                 SafeExecute(*this);
  186.         }
  187.         void Execute() 
  188.         {
  189.                 (obj_.*memFun_)();
  190.         }
  191. protected:
  192.         ObjScopeGuardImpl0(Obj& obj, MemFun memFun) 
  193.                 : obj_(obj), memFun_(memFun) {}
  194.         Obj& obj_;
  195.         MemFun memFun_;
  196. };

  197. template <class Obj, typename MemFun>
  198. inline ObjScopeGuardImpl0 MakeObjGuard(Obj& obj, MemFun memFun)
  199. {
  200.         return ObjScopeGuardImpl0::MakeObjGuard(obj, memFun);
  201. }

  202. template <class Obj, typename MemFun, typename P1>
  203. class ObjScopeGuardImpl1 : public ScopeGuardImplBase
  204. {
  205. public:
  206.         static ObjScopeGuardImpl1 MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
  207.         {
  208.                 return ObjScopeGuardImpl1(obj, memFun, p1);
  209.         }
  210.         ~ObjScopeGuardImpl1() throw() 
  211.         {
  212.                 SafeExecute(*this);
  213.         }
  214.         void Execute() 
  215.         {
  216.                 (obj_.*memFun_)(p1_);
  217.         }
  218. protected:
  219.         ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) 
  220.                 : obj_(obj), memFun_(memFun), p1_(p1) {}
  221.         Obj& obj_;
  222.         MemFun memFun_;
  223.         const P1 p1_;
  224. };

  225. template <class Obj, typename MemFun, typename P1>
  226. inline ObjScopeGuardImpl1 MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
  227. {
  228.         return ObjScopeGuardImpl1::MakeObjGuard(obj, memFun, p1);
  229. }

  230. template <class Obj, typename MemFun, typename P1, typename P2>
  231. class ObjScopeGuardImpl2 : public ScopeGuardImplBase
  232. {
  233. public:
  234.         static ObjScopeGuardImpl2 MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
  235.         {
  236.                 return ObjScopeGuardImpl2(obj, memFun, p1, p2);
  237.         }
  238.         ~ObjScopeGuardImpl2() throw() 
  239.         {
  240.                 SafeExecute(*this);
  241.         }
  242.         void Execute() 
  243.         {
  244.                 (obj_.*memFun_)(p1_, p2_);
  245.         }
  246. protected:
  247.         ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) 
  248.                 : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) {}
  249.         Obj& obj_;
  250.         MemFun memFun_;
  251.         const P1 p1_;
  252.         const P2 p2_;
  253. };

  254. template <class Obj, typename MemFun, typename P1, typename P2>
  255. inline ObjScopeGuardImpl2 MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
  256. {
  257.         return ObjScopeGuardImpl2::MakeObjGuard(obj, memFun, p1, p2);
  258. }

  259. #define CONCATENATE_DIRECT(s1, s2) s1##s2
  260. #define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
  261. #define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)

  262. #define ON_BLOCK_EXIT ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard
  263. #define ON_BLOCK_EXIT_OBJ ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard



  264. //////////////////////////////////////////////////////////////////////////////////////////
  265. //      janitor
  266. struct ICmd_
  267. {
  268.         virtual void Dismiss() const throw() = 0;
  269.         virtual ~ICmd_() throw() {}
  270. };

  271. template<typename T>
  272. class CmdAdaptor : public ICmd_, protected T
  273. {
  274. public:
  275.         template<typename Fun>
  276.                 CmdAdaptor(Fun fun) : T(fun) {}
  277.         template<typename Fun, typename P1>
  278.                 CmdAdaptor(Fun fun, P1 p1) : T(fun, p1) {}
  279.         template<typename Fun, typename P1, typename P2>
  280.                 CmdAdaptor(Fun fun, P1 p1, P2 p2) : T(fun, p1, p2) {}
  281.         template<typename Fun, typename P1, typename P2, typename P3>
  282.                 CmdAdaptor(Fun fun, P1 p1, P2 p2, P3 p3) : T(fun, p1, p2, p3) {}
  283.         void Dismiss() const throw()
  284.         {
  285.                 T::Dismiss();
  286.         }
  287. };

  288. class Janitor
  289. {
  290. public:
  291.         Janitor() throw() {}
  292.         template <typename F>
  293.                 Janitor(F pFun) : spCmd_(
  294.                 new CmdAdaptor >(pFun)) {}
  295.         template <typename F, typename P1>
  296.                 Janitor(F pFun, P1 p1) : spCmd_(
  297.                 new CmdAdaptor >(pFun, p1)) {}
  298.         template <typename F, typename P1, typename P2>
  299.                 Janitor(F pFun, P1 p1, P2 p2) : spCmd_(
  300.                 new CmdAdaptor >(pFun, p1, p2)) {}
  301.         template <typename F, typename P1, typename P2, typename P3>
  302.                 Janitor(F pFun, P1 p1, P2 p2, P3 p3) : spCmd_(
  303.                 new CmdAdaptor >(pFun, p1, p2, p3)) {}

  304.         Janitor(const Janitor& other) throw() : spCmd_(other.spCmd_) {} //VC++, Comeau need it!
  305.         Janitor& operator =(const Janitor& other) throw()
  306.         {
  307.                 if (spCmd_.get())
  308.                         spCmd_->Dismiss();
  309.                 spCmd_ = other.spCmd_;
  310.                 return *this;
  311.         }
  312.         void Dismiss() const throw()
  313.         {
  314.                 spCmd_->Dismiss();
  315.         }
  316. protected:
  317.         mutable std::auto_ptr spCmd_;
  318. };

  319. template<typename T>
  320. class ObjCmdAdaptor : public ICmd_, protected T
  321. {
  322. public:
  323.         template<typename Obj, typename MemFun>
  324.                 ObjCmdAdaptor(Obj& obj, MemFun memFun) : T(obj, memFun) {}
  325.         template<typename Obj, typename MemFun, typename P1>
  326.                 ObjCmdAdaptor(Obj& obj, MemFun memFun, P1 p1) : T(obj, memFun, p1) {}
  327.         template<typename Obj, typename MemFun, typename P1, typename P2>
  328.                 ObjCmdAdaptor(Obj& obj, MemFun memFun, P1 p1, P2 p2) : T(obj, memFun, p1, p2) {}
  329.         void Dismiss() const throw()
  330.         {
  331.                 T::Dismiss();
  332.         }
  333. };

  334. class ObjJanitor : protected Janitor
  335. {
  336. public:
  337.         using Janitor::Dismiss;
  338.         ObjJanitor() throw() {}

  339.         template <typename Obj, typename MemFun>
  340.                 ObjJanitor(Obj& obj, MemFun memFun)
  341.         {
  342.                 std::auto_ptr spTmp(
  343.                         new ObjCmdAdaptor >(obj, memFun));
  344.                 spCmd_ = spTmp;
  345.         }
  346.         template <typename Obj, typename MemFun, typename P1>
  347.                 ObjJanitor(Obj& obj, MemFun memFun, P1 p1)
  348.         {
  349.                 std::auto_ptr spTmp(
  350.                         new ObjCmdAdaptor >(obj, memFun, p1));
  351.                 spCmd_ = spTmp;
  352.         }
  353.         template <typename Obj, typename MemFun, typename P1, typename P2>
  354.                 ObjJanitor(Obj& obj, MemFun memFun, P1 p1, P2 p2)
  355.         {
  356.                 std::auto_ptr spTmp(
  357.                         new ObjCmdAdaptor >(obj, memFun, p1, p2));
  358.                 spCmd_ = spTmp;
  359.         }
  360. };


使用范例

  1. #include "stdafx.h"
  2. #include 
  3. #include 
  4. using namespace std;

  5. #include "janitor.hpp"
  6. class class1
  7. {
  8. public:
  9.     class1()
  10.     {
  11.     }
  12.     ~class1()
  13.     {
  14.     }
  15. public:
  16.     void test()
  17.     {
  18.         ObjJanitor ja(*this,&class1::testJanitor);
  19.     }
  20.     void testJanitor()
  21.     {
  22.         cout << "hello world" << endl;
  23.     }
  24. };

  25. int _tmain(int argc, _TCHAR* argv[])
  26. {
  27.     class1 c;
  28.     c.test();
  29.     return 0;
  30. }


二.controlled_module 可被关闭的线程类
 该类原型来自于一个叫“阿修罗”的原始类
  1. // controlled_module.hpp : 可主动关闭的boost线程类
  2. //
  3. #pragma once

  4. #include      
  5. #include      
  6. #include   
  7. #include 
  8. #include 

  9. #include "janitor.hpp"

  10. class   controlled_module_implement   :   boost::noncopyable   {   
  11.   public:   
  12.   controlled_module_implement()   :active_(false),command_exit_(false){}   
  13.   boost::condition   module_is_exit;   
  14.   boost::mutex   monitor;   
  15.   void   active(bool   ac)   
  16.   {boost::mutex::scoped_lock   lk(monitor);   if(!(active_=ac))module_is_exit.notify_all();else   command_exit_=false;}   
  17.   bool   command_exit(){boost::mutex::scoped_lock   lk(monitor);   return   command_exit_;}   
  18.   bool   active_,command_exit_;   
  19.     
  20.   };
  21.   class   controlled_module   :   boost::noncopyable   {   
  22.   public:   
  23.   virtual   void   run()
  24.   {
  25.       ObjJanitor   janitor(*impl_,&controlled_module_implement::active,false);   
  26.     impl_->active(true);   
  27.     {   
  28.         ObjJanitor   janitor(*this,&controlled_module::release);   
  29.         if(this->initialize())   
  30.         {   
  31.             m_live = true;
  32.             SetEvent(m_event_init);
  33.             while(!impl_->command_exit()   &&  this->islive() &&  this->work())
  34.             {
  35.             }
  36.         }
  37.         else
  38.         {
  39.             m_live = false;
  40.             SetEvent(m_event_init);
  41.         }
  42.     }  
  43.   }
  44.   bool   exit(unsigned   long   sec=0)
  45.   {
  46.   boost::mutex::scoped_lock   lk(impl_->monitor);   
  47.   impl_->command_exit_   =   true;   
  48.   while(impl_->active_)   
  49.   {   
  50.   if(sec)   
  51.   {   
  52.   boost::xtime   xt;   
  53.   boost::xtime_get(&xt,   boost::TIME_UTC);   
  54.   xt.sec   +=   sec;   
  55.   if(!impl_->module_is_exit.timed_wait(lk,xt))   
  56.   return   false;   
  57.   }   
  58.   else   
  59.   impl_->module_is_exit.wait(lk);   
  60.   }   
  61.   return   true;   
  62.   }
  63.   protected:   
  64.   controlled_module()
  65.   :impl_(new   controlled_module_implement)   
  66.   ,m_live(false)
  67.   ,m_event_init(0)
  68.   ,m_sleeptime(10)
  69.   {     
  70.   }   
  71.   virtual   ~controlled_module()
  72.   {
  73.       if(m_live)
  74.           stop();
  75.       delete   impl_;   
  76.   }
  77.   private:    
  78.       virtual   bool   initialize(){return true;} 
  79.       virtual   void   release(){}
  80.   protected:
  81.       virtual   bool   work()
  82.       {
  83.         Sleep(this->m_sleeptime);
  84.         return true;
  85.       }
  86.       int m_sleeptime;
  87.   private:   
  88.     bool m_live;
  89.     void * m_event_init;
  90.  controlled_module_implement*   impl_;   
  91.   public:
  92.     bool start()
  93.     {
  94.         m_event_init = CreateEvent(NULL,FALSE,FALSE,"");
  95.         boost::thread thd(boost::bind(&controlled_module::run,this));
  96.         ::WaitForSingleObject(m_event_init,INFINITE);
  97.         CloseHandle(m_event_init);
  98.         m_event_init = 0;
  99.         return m_live;
  100.     }
  101.     void stop()
  102.     {
  103.         m_live = false;
  104.         exit(1);
  105.     }
  106.     bool islive(){return m_live;}
  107.     void die()
  108.     {
  109.       m_live = false;
  110.         SetEvent(m_event_init);
  111.     }
  112.     void setsleeptime(int n)
  113.     {
  114.       m_sleeptime = n;
  115.     }
  116.   };
  117.     


  virtual   bool   initialize();   初始化
  virtual   void   release();   释放
  virtual   bool   work();   工作函数
  如果我们要创建一个可被关闭的线程,可以如下步骤:
  1)创建一个controlled_module 继承类
  2)实现3个虚拟函数
  3)用start(),stop()启动和停止线程
范例:
  1. //controlled_module demo
  2. #include "controlled_module.hpp"
  3. class thd: public controlled_module
  4. {
  5. public:
  6.     virtual bool initialize()
  7.     {
  8.         cout << "thd init" << endl;
  9.         return true;
  10.     }
  11.     virtual void release()
  12.     {
  13.         cout << "thd release" << endl;
  14.     }
  15.     virtual bool work()
  16.     {
  17.         //your work........
  18.         return controlled_module::work();
  19.     }
  20. };
  21. int _tmain(int argc, _TCHAR* argv[])
  22. {
  23.     thd t;
  24.     t.start();
  25.     char buf[10];
  26.     gets_s(buf,sizeof buf);
  27.     t.stop();
  28.     return 0;
  29. }


thd线程在启动以后,将循环执行work()函数,直到线程退出
阅读(1177) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~