C++线程锁封装

C++线程锁的封装,主要提供lock,unlock,require等操作,需要注意的是线程重复获取锁的问题,设置了一个count的计数器,该计算器之所以不考虑++,--的原子操作的问题,是因为该计数器本身就在lock与unlock中,所以本身是线程安全的。


另外mutable count是将count的变化操作防止在const方法中,保证方法语义。



  1. class TC_ThreadCond;  
  2.   
  3. /** 
  4.  * 线程互斥对象 
  5.  */  
  6. struct TC_ThreadMutex_Exception : public TC_Lock_Exception  
  7. {  
  8.     TC_ThreadMutex_Exception(const string &buffer) : TC_Lock_Exception(buffer){};  
  9.     TC_ThreadMutex_Exception(const string &buffer, int err) : TC_Lock_Exception(buffer, err){};  
  10.     ~TC_ThreadMutex_Exception() throw() {};  
  11. };  
  12.   
  13. /** 
  14. * 线程锁 
  15. */  
  16. class TC_ThreadMutex  
  17. {  
  18. public:  
  19.   
  20.     TC_ThreadMutex();  
  21.     virtual ~TC_ThreadMutex();  
  22.   
  23.     /** 
  24.      * 加锁 
  25.      */  
  26.     void lock() const;  
  27.   
  28.     /** 
  29.      * 尝试锁 
  30.      *  
  31.      * @return bool 
  32.      */  
  33.     bool tryLock() const;  
  34.   
  35.     /** 
  36.      * 解锁 
  37.      */  
  38.     void unlock() const;  
  39.   
  40.     /** 
  41.      * 加锁后调用unlock是否会解锁, 给TC_Monitor使用的 
  42.      * 永远返回true 
  43.      *  
  44.      * @return bool 
  45.      */  
  46.     bool willUnlock() const { return true;}  
  47.   
  48. protected:  
  49.   
  50.     // noncopyable  
  51.     TC_ThreadMutex(const TC_ThreadMutex&);  
  52.     void operator=(const TC_ThreadMutex&);  
  53.   
  54.     /** 
  55.      * 计数 
  56.      */  
  57.     int count() const;  
  58.   
  59.     /** 
  60.      * 计数 
  61.      */  
  62.     void count(int c) const;  
  63.   
  64.     friend class TC_ThreadCond;  
  65.   
  66. protected:  
  67.     mutable pthread_mutex_t _mutex;  
  68.   
  69. };  
  70.   
  71. /** 
  72. * 线程锁类 
  73. * 采用线程库实现 
  74. **/  
  75. class TC_ThreadRecMutex  
  76. {  
  77. public:  
  78.   
  79.     /** 
  80.     * 构造函数 
  81.     */  
  82.     TC_ThreadRecMutex();  
  83.   
  84.     /** 
  85.     * 析够函数 
  86.     */  
  87.     virtual ~TC_ThreadRecMutex();  
  88.   
  89.     /** 
  90.     * 锁, 调用pthread_mutex_lock 
  91.     * return : 返回pthread_mutex_lock的返回值 
  92.     */  
  93.     int lock() const;  
  94.   
  95.     /** 
  96.     * 解锁, pthread_mutex_unlock 
  97.     * return : 返回pthread_mutex_lock的返回值 
  98.     */  
  99.     int unlock() const;  
  100.   
  101.     /** 
  102.     * 尝试锁, 失败抛出异常 
  103.     * return : true, 成功锁; false 其他线程已经锁了 
  104.     */  
  105.     bool tryLock() const;  
  106.   
  107.     /** 
  108.      * 加锁后调用unlock是否会解锁, 给TC_Monitor使用的 
  109.      *  
  110.      * @return bool 
  111.      */  
  112.     bool willUnlock() const;  
  113. protected:  
  114.   
  115.     /** 
  116.      * 友元类 
  117.      */  
  118.     friend class TC_ThreadCond;  
  119.   
  120.     /** 
  121.      * 计数 
  122.      */  
  123.     int count() const;  
  124.   
  125.     /** 
  126.      * 计数 
  127.      */  
  128.     void count(int c) const;  
  129.   
  130. private:  
  131.     /** 
  132.     锁对象 
  133.     */  
  134.     mutable pthread_mutex_t _mutex;  
  135.     mutable int _count;  
  136. };  


  1. TC_ThreadMutex::TC_ThreadMutex()  
  2. {  
  3.     int rc;  
  4.     pthread_mutexattr_t attr;  
  5.     rc = pthread_mutexattr_init(&attr);  
  6.     assert(rc == 0);  
  7.   
  8.     rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);  
  9.     assert(rc == 0);  
  10.   
  11.     rc = pthread_mutex_init(&_mutex, &attr);  
  12.     assert(rc == 0);  
  13.   
  14.     rc = pthread_mutexattr_destroy(&attr);  
  15.     assert(rc == 0);  
  16.   
  17.     if(rc != 0)  
  18.     {xxx  
  19.         throw TC_ThreadMutex_Exception("[TC_ThreadMutex::TC_ThreadMutex] pthread_mutexattr_init error", rc);  
  20.     }  
  21. }  
  22.   
  23. TC_ThreadMutex::~TC_ThreadMutex()  
  24. {  
  25.     int rc = 0;  
  26.     rc = pthread_mutex_destroy(&_mutex);  
  27.     assert(rc == 0);  
  28. }  
  29.   
  30. void TC_ThreadMutex::lock() const  
  31. {  
  32.     int rc = pthread_mutex_lock(&_mutex);  
  33.     if(rc != 0)  
  34.     {  
  35.         if(rc == EDEADLK)  
  36.         {  
  37.             throw TC_ThreadMutex_Exception("[TC_ThreadMutex::lock] pthread_mutex_lock dead lock error", rc);  
  38.         }  
  39.         else  
  40.         {  
  41.             throw TC_ThreadMutex_Exception("[TC_ThreadMutex::lock] pthread_mutex_lock error", rc);  
  42.         }  
  43.     }  
  44. }  
  45.   
  46. bool TC_ThreadMutex::tryLock() const  
  47. {  
  48.     int rc = pthread_mutex_trylock(&_mutex);  
  49.     if(rc != 0 && rc != EBUSY)  
  50.     {  
  51.         if(rc == EDEADLK)  
  52.         {  
  53.             throw TC_ThreadMutex_Exception("[TC_ThreadMutex::tryLock] pthread_mutex_trylock dead lock error", rc);  
  54.         }  
  55.         else  
  56.         {  
  57.             throw TC_ThreadMutex_Exception("[TC_ThreadMutex::tryLock] pthread_mutex_trylock error", rc);  
  58.         }  
  59.     }  
  60.     return (rc == 0);  
  61. }  
  62.   
  63. void TC_ThreadMutex::unlock() const  
  64. {  
  65.     int rc = pthread_mutex_unlock(&_mutex);  
  66.     if(rc != 0)  
  67.     {  
  68.         throw TC_ThreadMutex_Exception("[TC_ThreadMutex::unlock] pthread_mutex_unlock error", rc);  
  69.     }  
  70. }  
  71.   
  72. int TC_ThreadMutex::count() const  
  73. {  
  74.     return 0;  
  75. }  
  76.   
  77. void TC_ThreadMutex::count(int c) const  
  78. {  
  79. }  
  80.   
  81. ///  
  82. TC_ThreadRecMutex::TC_ThreadRecMutex()  
  83. : _count(0)  
  84. {  
  85.     int rc;  
  86.   
  87.     pthread_mutexattr_t attr;  
  88.     rc = pthread_mutexattr_init(&attr);  
  89.     if(rc != 0)  
  90.     {  
  91.         throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_init error", rc);  
  92.     }  
  93.     rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);  
  94.     if(rc != 0)  
  95.     {  
  96.         throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_settype error", rc);  
  97.     }  
  98.   
  99.     rc = pthread_mutex_init(&_mutex, &attr);  
  100.     if(rc != 0)  
  101.     {  
  102.         throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutex_init error", rc);  
  103.     }  
  104.   
  105.     rc = pthread_mutexattr_destroy(&attr);  
  106.     if(rc != 0)  
  107.     {  
  108.         throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_destroy error", rc);  
  109.     }  
  110. }  
  111.   
  112. TC_ThreadRecMutex::~TC_ThreadRecMutex()  
  113. {  
  114.     while (_count)  
  115.     {  
  116.         unlock();  
  117.     }  
  118.   
  119.     int rc = 0;  
  120.     rc = pthread_mutex_destroy(&_mutex);  
  121.     assert(rc == 0);  
  122. }  
  123.   
  124. int TC_ThreadRecMutex::lock() const  
  125. {  
  126.     int rc = pthread_mutex_lock(&_mutex);  
  127.     if(rc != 0)  
  128.     {  
  129.         throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::lock] pthread_mutex_lock error", rc);  
  130.     }  
  131.   
  132.     if(++_count > 1)  
  133.     {  
  134.         rc = pthread_mutex_unlock(&_mutex);  
  135.         assert(rc == 0);  
  136.     }  
  137.   
  138.     return rc;  
  139. }  
  140.   
  141. int TC_ThreadRecMutex::unlock() const  
  142. {  
  143.     if(--_count == 0)  
  144.     {  
  145.         int rc = 0;  
  146.         rc = pthread_mutex_unlock(&_mutex);  
  147.         return rc;  
  148.     }  
  149.     return 0;  
  150. }  
  151.   
  152. bool TC_ThreadRecMutex::tryLock() const  
  153. {  
  154.     int rc = pthread_mutex_trylock(&_mutex);  
  155.     if(rc != 0 )  
  156.     {  
  157.         if(rc != EBUSY)  
  158.         {  
  159.             throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::tryLock] pthread_mutex_trylock error", rc);  
  160.         }  
  161.     }  
  162.     else if(++_count > 1)  
  163.     {  
  164.         rc = pthread_mutex_unlock(&_mutex);  
  165.         if(rc != 0)  
  166.         {  
  167.             throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::tryLock] pthread_mutex_unlock error", rc);  
  168.         }  
  169.     }  
  170.     return (rc == 0);  
  171. }  
  172.   
  173. bool TC_ThreadRecMutex::willUnlock() const  
  174. {  
  175.     return _count == 1;  
  176. }  
  177.   
  178. int TC_ThreadRecMutex::count() const  
  179. {  
  180.     int c   = _count;  
  181.     _count  = 0;  
  182.     return c;  
  183. }  
  184.   
  185. void TC_ThreadRecMutex::count(int c) const  
  186. {  
  187.     _count = c;  
  188. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值