MuteLock
使用类来封装该功能时需要注意,该类不支持拷贝构造和赋值。
class MutexLock: boost::noncopyable{
public:
// Initialize mutex_
MutexLock():holder_(0){
pthread_mutex_init(&mutex_, NULL);
}
// Destroy mutex_
~MutexLock(){
assert(holder_ == 0);
pthread_mutex_destroy(&mutex_);
}
// Check the current thread is locked or not
bool isLockedByThisThread(){
return holder_ == CurrentThread::tid();
}
// assert is used to debug
void assertLocked(){
assert(isLockedByThisThread());
}
// Lock the thread
// 注意,lock与unlock的调用顺序不能错,否则可能会导致一些不可预料的后果
// 其次,lock与unlock只能在MutexLockGuard中调用
void lock(){
pthread_mutex_lock(&mutex_);
holder_ = CurrentThread::tid();
}
// Unlock the thread
void unlock(){
holder_ = 0;
pthread_mutex_unlock(&mutex_);
}
// Get the mutex
pthread_mutex_t* getThreadMutex(){
return &mutex_;
}
private:
pthread_mutex_t mutex_; // The lock
pid_t holder_; // Indicates which thread owns the lock
];
MutexLockGuard
MutexLockGuard 保证了互斥锁可以正确的使用,
class MutexLockGuard: boost::noncopyable{
public:
explicit MutexLockGuard(MutexLock &mutex): mutex_(mutex){
mutex.lock();
}
~MuteLockGuard(){
mutex_.unlock();
}
private:
MutexLock& mutex_;
};
// 防止MutexLockGuard 临时变量的产生,其会锁住临界区,但又会随即释放临界区的锁,造成性能浪费等问题
#define MutexLockGuard(x) static_assert(false, "missing mutex guard var name")
// 为何不使用assert的原因,在与assert在release中为空语句,为了避免
// 这种问题,因此使用c++11中的static_assert,在编译器解决问题
Condition
Condition 封装了Pthreads condition variable
class Condition: boost noncopyable{
explicit Condition(MutexLock &mutex): mutex_(mutex){
pthread_cond_init(&pcond_, NULL);
}
~Condition(){
pthread_cond_destroy(&pcond_);
}
void wait(){
pthread_cond_wait(&pcond_, mutex_.getPthreadMutex());
}
void notify(){
pthread_cond_signal(&pcond_);
}
void notifyAll(){
pthread_cond_broadcast(&pcond_);
}
private:
MutexLock &mutex_;
pthread_cond_t pcond_;
};
注意: 若一个class要同时包含MutexLock 和 Condition, 请注意它们的声明顺序和初始化顺序,mutex_ 应该先于 condition_ 构造,并作为后者的参数。
for instance
class CountDownLatch{
public:
// mutex_ 先于 condition_ 进行构造
CountDownLatch(int count): mutex_(), condition_(mutex_), count_(count){
}
private:
// 注意mutex,condition的顺序
mutable MutexLock mutex_;
Condition condition_;
int count_;
};