0 前言
对于mutex锁的使用,mutex的加锁和解锁操作是需要配对使用的。
考虑下面这种情况:
MutexLock mutexLock;// MutexLock参见后面"1 mutex锁实现类"
void f()
{
mutexLock.lock();
...
if (条件)
{
return;// 函数提前return
}
mutexLock.unlock();
}
该种情况,由于程序提前return退出,导致mutexLock未能解锁,从而出现问题。
因此,借鉴RAII(Resource Acquisition Is Initialization),资源获取即初始化思想,由类来管理mutexLock对象,利用类的构造、析构函数以及对象的生命周期/作用域来实现mutexLock对象的动态管理。这样便不需要手动负责mutexLock对象的创建和销毁了。
1 mutex锁实现类
class MutexLock : noncopyable
{
public:
MutexLock()
{
// 创建锁
pthread_mutex_init(&mutex_, NULL);
}
~MutexLock()
{
// 销毁锁
pthread_mutex_destroy(&mutex_);
}
// 加锁
void lock() ACQUIRE()
{
pthread_mutex_lock(&mutex_);// 调用pthread_mutex_lock()实现
}
// 解锁
void unlock() RELEASE()
{
pthread_mutex_unlock(&mutex_);
}
// 获取mutex对象
pthread_mutex_t* getPthreadMutex() /* non-const */
{
// 返回mutex_成员变量
return &mutex_;
}
private:
pthread_mutex_t mutex_;
};
2 mutex锁管理类
其实这就是C++11中std::lock_guard
锁管理器的实现原理。
class SCOPED_CAPABILITY MutexLockGuard : noncopyable
{
public:
// 获取资源
// mutex对象的生成和销毁不归MutexLockGuard类管理
// MutexLock与MutexLockGuard类的关系是关联关系
explicit MutexLockGuard(MutexLock& mutex) ACQUIRE(mutex)
: mutex_(mutex)
{
// 调用lock
mutex_.lock();
}
// 释放资源
~MutexLockGuard() RELEASE()
{
mutex_.unlock();
}
private:
MutexLock& mutex_;// 注意是mutex&引用 mutex对象的生成和销毁不归MutexLockGuard类管理
};
3 使用MutexLockGuard类后的程序
MutexLcok mutexLock;
void f()
{
MutexLockGuard lock(mutexLock);// 该对象的作用域为f()函数 函数体
...
if (条件)
{
return;// 函数return后,MutexLockGuard类的对象lock也会失效--离开作用域,
//自动调用析构函数(mutexLock.unlock())将mutex解锁
}
}