C++线程锁封装
来源:互联网 发布:安卓手机安装windows 编辑:程序博客网 时间:2024/06/03 16:11
C++线程锁的封装,主要提供lock,unlock,require等操作,需要注意的是线程重复获取锁的问题,设置了一个count的计数器,该计算器之所以不考虑++,--的原子操作的问题,是因为该计数器本身就在lock与unlock中,所以本身是线程安全的。
另外mutable count是将count的变化操作防止在const方法中,保证方法语义。
- class TC_ThreadCond;
- /**
- * 线程互斥对象
- */
- struct TC_ThreadMutex_Exception : public TC_Lock_Exception
- {
- TC_ThreadMutex_Exception(const string &buffer) : TC_Lock_Exception(buffer){};
- TC_ThreadMutex_Exception(const string &buffer, int err) : TC_Lock_Exception(buffer, err){};
- ~TC_ThreadMutex_Exception() throw() {};
- };
- /**
- * 线程锁
- */
- class TC_ThreadMutex
- {
- public:
- TC_ThreadMutex();
- virtual ~TC_ThreadMutex();
- /**
- * 加锁
- */
- void lock() const;
- /**
- * 尝试锁
- *
- * @return bool
- */
- bool tryLock() const;
- /**
- * 解锁
- */
- void unlock() const;
- /**
- * 加锁后调用unlock是否会解锁, 给TC_Monitor使用的
- * 永远返回true
- *
- * @return bool
- */
- bool willUnlock() const { return true;}
- protected:
- // noncopyable
- TC_ThreadMutex(const TC_ThreadMutex&);
- void operator=(const TC_ThreadMutex&);
- /**
- * 计数
- */
- int count() const;
- /**
- * 计数
- */
- void count(int c) const;
- friend class TC_ThreadCond;
- protected:
- mutable pthread_mutex_t _mutex;
- };
- /**
- * 线程锁类
- * 采用线程库实现
- **/
- class TC_ThreadRecMutex
- {
- public:
- /**
- * 构造函数
- */
- TC_ThreadRecMutex();
- /**
- * 析够函数
- */
- virtual ~TC_ThreadRecMutex();
- /**
- * 锁, 调用pthread_mutex_lock
- * return : 返回pthread_mutex_lock的返回值
- */
- int lock() const;
- /**
- * 解锁, pthread_mutex_unlock
- * return : 返回pthread_mutex_lock的返回值
- */
- int unlock() const;
- /**
- * 尝试锁, 失败抛出异常
- * return : true, 成功锁; false 其他线程已经锁了
- */
- bool tryLock() const;
- /**
- * 加锁后调用unlock是否会解锁, 给TC_Monitor使用的
- *
- * @return bool
- */
- bool willUnlock() const;
- protected:
- /**
- * 友元类
- */
- friend class TC_ThreadCond;
- /**
- * 计数
- */
- int count() const;
- /**
- * 计数
- */
- void count(int c) const;
- private:
- /**
- 锁对象
- */
- mutable pthread_mutex_t _mutex;
- mutable int _count;
- };
- TC_ThreadMutex::TC_ThreadMutex()
- {
- int rc;
- pthread_mutexattr_t attr;
- rc = pthread_mutexattr_init(&attr);
- assert(rc == 0);
- rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
- assert(rc == 0);
- rc = pthread_mutex_init(&_mutex, &attr);
- assert(rc == 0);
- rc = pthread_mutexattr_destroy(&attr);
- assert(rc == 0);
- if(rc != 0)
- {xxx
- throw TC_ThreadMutex_Exception("[TC_ThreadMutex::TC_ThreadMutex] pthread_mutexattr_init error", rc);
- }
- }
- TC_ThreadMutex::~TC_ThreadMutex()
- {
- int rc = 0;
- rc = pthread_mutex_destroy(&_mutex);
- assert(rc == 0);
- }
- void TC_ThreadMutex::lock() const
- {
- int rc = pthread_mutex_lock(&_mutex);
- if(rc != 0)
- {
- if(rc == EDEADLK)
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadMutex::lock] pthread_mutex_lock dead lock error", rc);
- }
- else
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadMutex::lock] pthread_mutex_lock error", rc);
- }
- }
- }
- bool TC_ThreadMutex::tryLock() const
- {
- int rc = pthread_mutex_trylock(&_mutex);
- if(rc != 0 && rc != EBUSY)
- {
- if(rc == EDEADLK)
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadMutex::tryLock] pthread_mutex_trylock dead lock error", rc);
- }
- else
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadMutex::tryLock] pthread_mutex_trylock error", rc);
- }
- }
- return (rc == 0);
- }
- void TC_ThreadMutex::unlock() const
- {
- int rc = pthread_mutex_unlock(&_mutex);
- if(rc != 0)
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadMutex::unlock] pthread_mutex_unlock error", rc);
- }
- }
- int TC_ThreadMutex::count() const
- {
- return 0;
- }
- void TC_ThreadMutex::count(int c) const
- {
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TC_ThreadRecMutex::TC_ThreadRecMutex()
- : _count(0)
- {
- int rc;
- pthread_mutexattr_t attr;
- rc = pthread_mutexattr_init(&attr);
- if(rc != 0)
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_init error", rc);
- }
- rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- if(rc != 0)
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_settype error", rc);
- }
- rc = pthread_mutex_init(&_mutex, &attr);
- if(rc != 0)
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutex_init error", rc);
- }
- rc = pthread_mutexattr_destroy(&attr);
- if(rc != 0)
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_destroy error", rc);
- }
- }
- TC_ThreadRecMutex::~TC_ThreadRecMutex()
- {
- while (_count)
- {
- unlock();
- }
- int rc = 0;
- rc = pthread_mutex_destroy(&_mutex);
- assert(rc == 0);
- }
- int TC_ThreadRecMutex::lock() const
- {
- int rc = pthread_mutex_lock(&_mutex);
- if(rc != 0)
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::lock] pthread_mutex_lock error", rc);
- }
- if(++_count > 1)
- {
- rc = pthread_mutex_unlock(&_mutex);
- assert(rc == 0);
- }
- return rc;
- }
- int TC_ThreadRecMutex::unlock() const
- {
- if(--_count == 0)
- {
- int rc = 0;
- rc = pthread_mutex_unlock(&_mutex);
- return rc;
- }
- return 0;
- }
- bool TC_ThreadRecMutex::tryLock() const
- {
- int rc = pthread_mutex_trylock(&_mutex);
- if(rc != 0 )
- {
- if(rc != EBUSY)
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::tryLock] pthread_mutex_trylock error", rc);
- }
- }
- else if(++_count > 1)
- {
- rc = pthread_mutex_unlock(&_mutex);
- if(rc != 0)
- {
- throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::tryLock] pthread_mutex_unlock error", rc);
- }
- }
- return (rc == 0);
- }
- bool TC_ThreadRecMutex::willUnlock() const
- {
- return _count == 1;
- }
- int TC_ThreadRecMutex::count() const
- {
- int c = _count;
- _count = 0;
- return c;
- }
- void TC_ThreadRecMutex::count(int c) const
- {
- _count = c;
- }
0 0
- C++线程锁封装
- C++线程锁封装
- C语言封装线程与日志类
- BOOST mutex 线程锁封装
- 线程封装
- C语言封装的轻量线程环境 Protothreads
- 用c++简单的封装线程c中互斥锁
- c印记(十四):跨平台线程封装
- 线程锁的基本概念与简单封装
- C#--封装
- 【C#】封装
- linux c 线程锁
- object-c 线程锁
- 线程的封装
- 线程类封装(1)
- 线程类封装(2)
- 线程类封装(3)
- 线程类封装(4)
- 对 UIView 的 setNeedsLayout、 layoutIfNeeded 和 layoutSubviews 方法之间的关系解释
- Android初学习 - EditText、TextView中文本的获取和设置
- 题目1 : 骨牌覆盖问题·一 (线性递推+矩阵快速幂)
- 第六周项目5——有元类
- 反射类入门学习
- C++线程锁封装
- 黑马程序员_日记51_泛型定义在接口上
- 模运算 NOJ 1037
- ERP系统应用效果表现在哪些方面
- PHP通过OpenSSL生成证书、密钥并且加密解密数据
- Poj3723 最大权森林
- ORACLE查询当前最早的事务的开始时间
- 孙其功陪你学之——Spark 正则化和SparkSQL
- JVM调优总结(九)-新一代的垃圾回收算法