RAII封装mutex

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


你可能感兴趣的:(C++)