Linux组件封装(一) 互斥锁MutexLock
由于pthread系列的函数都是成功时返回0,我们需要一段判断处理错误的代码:
#define TINY_CHECK(exp)\ if(!exp)\ { \ fprintf(stderr, "File : %s, Line : %d Exp : ["#exp"] is true, abort.\n", __FILE__, __LINE__); abort();\ }
MutexLock的封装如下:
1 #ifndef MUTEXLOCK_H 2 #define MUTEXLOCK_H 3 4 #include "NonCopyable.h" 5 #include <pthread.h> 6 #include <stdlib.h> 7 #include <stdio.h> 8 #define TINY_CHECK(exp)\ 9 if(!exp)\ 10 { \ 11 fprintf(stderr, "File : %s, Line : %d Exp : ["#exp"] is true, abort.\n", __FILE__, __LINE__); abort();\ 12 } 13 14 15 16 class MutexLock : NonCopyable 17 { 18 friend class Condition; 19 public: 20 MutexLock(); 21 ~MutexLock(); 22 void lock(); 23 void unlock(); 24 25 bool isLocked() const { return _isLock; } 26 pthread_mutex_t *getMutexPtr() { return &_mutex; } 27 28 private: 29 void restoreMutexStatus() 30 { _isLock = true; } 31 32 pthread_mutex_t _mutex; 33 bool _isLock; 34 }; 35 36 37 class MutexLockGuard : NonCopyable //将锁封装到MutexLockGuard中, 38 { //这样只需定义一个对象,便可 39 public: //便可自动上锁,对象销毁时自动解锁 40 MutexLockGuard(MutexLock &mutex) 41 :_mutex(mutex) 42 { _mutex.lock(); } 43 44 ~MutexLockGuard() 45 { _mutex.unlock(); } 46 47 private: 48 MutexLock &_mutex; 49 }; 50 #define MutexLockGuard(m) "ERROR" 51 52 #endif
cpp文件如下:
1 #include "MutexLock.h" 2 #include <assert.h> 3 4 MutexLock::MutexLock() 5 :_isLock(false) 6 { 7 TINY_CHECK(!pthread_mutex_init(&_mutex, NULL)); 8 } 9 10 MutexLock::~MutexLock() 11 { 12 assert(!isLocked()); 13 TINY_CHECK(!pthread_mutex_destroy(&_mutex)); 14 } 15 16 void MutexLock::lock() 17 { 18 TINY_CHECK(!pthread_mutex_lock(&_mutex)); 19 _isLock = true; 20 } 21 22 void MutexLock::unlock() 23 { 24 _isLock = false; 25 TINY_CHECK(!pthread_mutex_unlock(&_mutex)); 26 }
当然,有一种使用方式是错误的,例如:
size_t Buffer::size() const
{
MutexLockGuard(mutex_);
return queue_.size();
}
这段代码的加锁周期仅在那一行有效,所以该种方法是错误的,所以,我们定义一个宏:
#define MutexLockGuard(m) "Error"
这样当错误使用时,会导致编译错误,使我们早些发现问题。