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_;};