RAII封装mutex
来源:互联网 发布:linux c程序杀死进程 编辑:程序博客网 时间:2024/05/19 04:54
采用RAII手法封转mutex使得mutex由栈上对象管理,能保证自动解锁不会重复解锁,加解锁在同一个线程,std::lock_guadr<>,std::unique_lock<>具备这样的功能,但是现在的g++还不支持c++11.
互斥量MutexLock的RAII封装:成员变量pthread_mutex_t mutex和pid_t holder。MutexLock调用pthread_mutex_init初始化mutex并holder=0;lock()调用pthread_mutex_init和holder为当前加锁线程id;unlock()调用pthread_mutex_unlock和将holder置为0;isLockedByThisThread()判断是否为本线程锁住;getPthreadMutex()返回mutex的指针;assertLocked()判断mutex是否锁住;设置friend class Condition互斥量安全加解锁对象MutexLockGuard:成员变量MutexLock。MutexLockGuard(MutexLock& mutex)对mutex上锁,MutexLockGuard()解锁。该封装实现了栈对象多次安全加解锁机制
条件变量Condition的封装:成员变量有mutexlock和pthread_cond_t;成员函数:Condition(mutex)需要一个mutexlock参数并初始化条件变量;~Conditon()销毁条件变量;wait()调用mutexlock锁住并pthread_cond_wait;waitForSeconds()是否超时;notif()调用pthread_cond_signal;notifyAll()调用pthread_cond_broadcast
#include<iostream>#include<pthread.h>#include<boost/utility.hpp>#include<string>#include<unistd.h>#include<stdexcept>using namespace std;using namespace boost;template<typename Mutex>//模板类封装class _LockGuard:boost::noncopyable{ public: explicit _LockGuard(Mutex& m):m_(m){ m_.lock(); } ~_LockGuard(){ m_.unlock(); } private: Mutex &m_;};class MutexLock:noncopyable{ public: MutexLock(){ pthread_mutex_init(&m_mutex,NULL); } ~MutexLock(){ pthread_mutex_destroy(&m_mutex); } void lock(){ pthread_mutex_lock(&m_mutex); } void unlock(){ pthread_mutex_unlock(&m_mutex); } private: pthread_mutex_t m_mutex;};class MutexLockGuard:noncopyable{ public: explicit MutexLockGuard(MutexLock &mutex):m_mutex(mutex){ m_mutex.lock(); } ~MutexLockGuard(){ m_mutex.unlock(); } private: MutexLock &m_mutex;};MutexLock lock;void print_even (int x) { if (x%2==0) std::cout << x << " is even\n"; else throw (std::logic_error("not even"));}void* print_thread_id (void *x) { int id=*(int*)x; try { // using a local lock_guard to lock mtx guarantees unlocking on destruction / exception: MutexLockGuard lck (lock); print_even(id); } catch (std::logic_error&) { std::cout << "[exception caught]\n"; }}void* _print_thread_id (void* x) { int id=*(int*) x; try { // using a local lock_guard to lock mtx guarantees unlocking on destruction / exception: _LockGuard<MutexLock> lck (lock); print_even(id); } catch (std::logic_error&) { std::cout << "[exception caught]\n"; } pthread_exit(0);}int main(){ pthread_t pid[10]; for(int i=0;i<10;i++){ if(pthread_create(&pid[i],NULL,print_thread_id,&i)<0)//_print_thread_id cout<<"pthread_create error"<<endl; } return 0;}
g++ -o raii_mutex raii_mutex.cpp -lpthread后执行结果可变,上面测试代码违背了不使用跨线程的mutex原则。
#include<iostream>#include<string>#include<unistd.h>#include<pthread.h>#include<assert.h>#include<boost/utility.hpp>using namespace std;using namespace boost;class Mutex:noncopyable{ public: Mutex(){ pthread_mutex_init(&mutex,NULL); } void lock(){ pthread_mutex_lock(&mutex); } void unlock(){ pthread_mutex_unlock(&mutex); } pthread_mutex_t& get(){ return mutex; } private: pthread_mutex_t mutex;};class MutexLockGuard:noncopyable{ public: explicit MutexLockGuard(Mutex& mutex):mutex_(mutex){ mutex_.lock(); } ~MutexLockGuard(){ mutex_.unlock(); } private: Mutex& mutex_;};class Condition:noncopyable{ public: explicit Condition(Mutex& mutex):mutex_(mutex){ pthread_cond_init(&pcond_,NULL); } ~Condition(){ pthread_cond_destroy(&pcond_); } void wait(){ pthread_cond_wait(&pcond_,&mutex_.get()); } void notify(){ pthread_cond_signal(&pcond_); } void notifyALL(){ pthread_cond_broadcast(&pcond_); } private: Mutex& mutex_; pthread_cond_t pcond_;};class CountDownLatch{ public: CountDownLatch(int count):mutex_(),condition_(mutex_),count_(count){}//初始化顺序和成员声明一致 void wait(){ MutexLockGuard lock(mutex_); while(count_>0) condition_.wait(); } void countDown(){ MutexLockGuard lock(mutex_); --count_; if(count_==0) condition_.notifyALL(); } private: mutable Mutex mutex_;//注意声明顺序 Condition condition_; int count_;};
- RAII封装mutex
- RAII手法封装互斥锁
- RAII封装TCP连接
- RAII手法封装互斥锁
- Thread系列的RAII封装
- Mutex的简单封装
- c++ 封装 mutex
- Linux mutex 封装
- 封装 shared::mutex
- RAII 想到AutoLock,Mutex类和C++11中的unique_lock
- RAII
- RAII
- RAII
- RAII
- RAII
- RAII
- RAII
- RAII
- hdu 1513 Palindrome
- Meta源码分析
- 静态包含 & 动态包含
- 分布式消息中间件 MetaQ 作者庄晓丹专访
- 再次理解封装继承多态
- RAII封装mutex
- Code Fragment-简单的数据类直接使用public字段来访问设值。
- MySql存储过程 游标(Cursor)
- Metaq原理与应用
- 【概率论】频率与概率
- ubuntu 运行android模拟器(emulator)零星笔记、心得
- mysql 存储过程 (一) 基础
- 还是先学好这些框架吧
- 解决Hibernate session is closed的一种可行性方案