RAII:互斥量

        RAII(资源获取即初始化)基本技术原理很简单,如果希望保持对某个重要资源的跟踪,那么创建一个对象,并将资源的生命期和对象的生命期相关联。这样的话,就可以利用c++复杂老练的对象管理机制来管理资源。最简单的形式是,当你构造一个对象的时候,其构造对象会获得一份资源,而析构函数则释放这份资源。采用对象管理资源,即使碰到意外的return、异常(C++保证如果抛出了异常,局部对象就会被销毁)甚至是邪恶的goto,均可以释放资源。

#include<iostream>
#include<exception>
#include<pthread.h>
#include<unistd.h>
#include<string>
#include<boost/noncopyable.hpp>
using namespace std;
using namespace boost;
class Mutex:noncopyable{
    public:
        Mutex(){
            pthread_mutex_init(&mutex,NULL);
        }
        void lock() const{
            pthread_mutex_lock(&mutex);
        }
        void unlock() const{
            pthread_mutex_unlock(&mutex);
        }
        ~Mutex(){
            cout<<"Mutex::unlock"<<endl;
            pthread_mutex_destroy(&mutex);
        }
    private:
        mutable pthread_mutex_t mutex;
};
class MutexLockGuard:noncopyable{
    public:
        explicit MutexLockGuard(Mutex& mutex):mutex_(mutex){//显示构造
            mutex_.lock();
        }
        ~MutexLockGuard(){
            mutex_.unlock();
        }
    private:
        Mutex& mutex_;//注意这里是引用!
};
Mutex mutex;
pthread_mutex_t mutex_=PTHREAD_MUTEX_INITIALIZER;
void fun(){
    pthread_mutex_lock(&mutex_);
    MutexLockGuard lock(mutex );//这里开始时犯了一个错误MutexLockGuard(mutex)...汗
    throw 1;
    pthread_mutex_unlock(&mutex_);
    cout<<"pthread_mutex_unlock"<<endl;//由于抛出异常该句不执行,可见某些情况让lock和unlock不配对
}
int main(){
    try{//throw抛出异常时会清理该块内的对象
        fun();
    }catch(int &temp){//catch会将将抛出的异常对象复制拷贝,如果catch参数是传值的,则拷贝构造一个新的对象作为catch语句的参数的值。在该catch语句结束时,先析构catch的传值的参数对象,然后析构throw语句抛出的异常对象。引用参数是为了效率。throw抛出的异常对象和catch实行严格匹配,不允许类型转换。
        cout<<"异常对象:"<<temp<<endl;
    }
    return 0;
}

执行结果:

异常对象:1
Mutex::unlock


你可能感兴趣的:(RAII互斥量)