在《Unix下的线程互斥量》一文中我们使用Thread_Mutex来保护线程共享资源,但如果互斥体上锁之后没有解锁就会发生死锁。这是一个很普遍的错误,我们采用Scope Lock模式,我们构造对象Scope_Mutex,其中构造函数对互斥体加锁,析构函数对互斥体解锁。C++保证了析构函数一定会被调用,所以即使是有异常抛出,互斥体也总是会被正确的解锁。下面给出Scope_Mutex的具体实现:
class Scope_Mutex
{
private:
Thread_Mutex mMutex;
Scope_Mutex(const Scope_Mutex&);
Scope_Mutex& operator=(const Scope_Mutex&);
public:
// 构造时对互斥量进行加锁
explicit Scope_Mutex(Thread_Mutex &m) : mMutex(m)
{
mMutex.lock();
}
// 析构时对互斥量进行解锁
~Scope_Mutex()
{
mMutex.unlock();
}
};
class Thread_Mutex {
public:
/*
* 构造函数
*/
Thread_Mutex() {
assert(pthread_mutex_init(&_mutex, NULL) == 0);
}
/*
* 析造函数
*/
~Thread_Mutex() {
//销毁互斥量
pthread_mutex_destroy(&_mutex);
}
/*
* 加锁
*/
void lock ()
{
int error;
//锁住互斥量
error = pthread_mutex_lock(&_mutex);
if (error != 0)
{
errno = error;
perror("Mutex lock");
abort();
}
}
/*
* 解锁
*/
void unlock()
{
int error;
//解锁互斥量
error = pthread_mutex_unlock(&_mutex);
if (error != 0)
{
errno = error;
perror("Mutex unlock");
abort();
}
}
protected:
pthread_mutex_t _mutex;
};