互斥锁封装:Mutex.h
Mutex类:对pthread_mutex_t 封装,提供了lock 、unlock 、是否被当前线程锁了isLockedByThisThread 、assertLocked 四个方法
MutexLockGard类:通过传递Mutex引用,在构造函数中对其加锁,析构中对其解锁----RAII(资源的地点是构造函数,释放点是析构函数)
#ifndef MUDUO_BASE_MUTEX_H
#define MUDUO_BASE_MUTEX_H
#include <muduo/base/CurrentThread.h>
#include <boost/noncopyable.hpp>
#include <assert.h>
#include <pthread.h>
namespace muduo
{
class MutexLock : boost::noncopyable
{
public:
MutexLock()
: holder_(0)
{
int ret = pthread_mutex_init(&mutex_, NULL);
assert(ret == 0);(void) ret;
}
~MutexLock()
{
assert(holder_ == 0);
int ret = pthread_mutex_destroy(&mutex_);
assert(ret == 0);(void) ret;
}
bool isLockedByThisThread()
{
return holder_ == CurrentThread::tid();
}
void assertLocked()
{
assert(isLockedByThisThread());
}
void lock()
{
pthread_mutex_lock(&mutex_);
holder_= CurrentThread::tid();
}
void unlock()
{
holder_ = 0;
pthread_mutex_unlock(&mutex_);
}
pthread_mutex_t* getPthreadMutex()
{
return &mutex_;
}
private:
pthread_mutex_t mutex_;
pid_t holder_;
};
class MutexLockGuard : boost::noncopyable
{
public:
explicit MutexLockGuard(MutexLock& mutex)
: mutex_(mutex)//mutex_引用初始化
{
mutex_.lock();
}
~MutexLockGuard()
{
mutex_.unlock();
}
private:
MutexLock& mutex_;//注意是 引用
};
}
//MutexLockGuard构造了 但是没有变量名来接受,就会立马析构
#define MutexLockGuard(x) error "Missing guard object name"
#endif
条件变量的封装:Condition.h
conditon构造函数中传递MutexLock的引用
时间函数: time( )--秒级, gettimeofday---微妙 , clock_gettime --纳秒 , _ftime ---毫秒
#ifndef MUDUO_BASE_CONDITION_H
#define MUDUO_BASE_CONDITION_H
#include <muduo/base/Mutex.h>
#include <boost/noncopyable.hpp>
#include <pthread.h>
#include <errno.h>
namespace muduo
{
class Condition : boost::noncopyable
{
public:
explicit Condition(MutexLock& mutex)
: mutex_(mutex)
{
pthread_cond_init(&pcond_, NULL);
}
~Condition()
{
pthread_cond_destroy(&pcond_);
}
void wait()
{
pthread_cond_wait(&pcond_, mutex_.getPthreadMutex());
}
//超时返回true,否则返回false
bool waitForSeconds(int seconds)
{
struct timespec abstime;
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += seconds;
return ETIMEDOUT == pthread_cond_timedwait(&pcond_, mutex_.getPthreadMutex(), &abstime);
}
void notify()
{
pthread_cond_signal(&pcond_);
}
void notifyAll()
{
pthread_cond_broadcast(&pcond_);
}
private:
MutexLock& mutex_;//注意是引用
pthread_cond_t pcond_;
};
}
#endif
倒计时类封装:CountDownLatch.cc CountDownLatch.h
condition 与mutex都所以自己私有的,不是外边传进来的。
发号通知-报数的人,不断调用CountDownLatch::countDown( ) 减数,减到0,就通知其他等待的人
等待命令的人,调用CountDownLatch::wait()等待
但是所有人都要调用同一个CountDownLatch示例(即统一condition、mutex)
注意mutext_是mutable类型,因为 getC
ount成员函数是const类型,不能修改此实例,但是getCount用到了锁,要修改mutex_,为了可以只修改锁,而不修改其他变量,所以把锁表明mutable类型
//countDownLatch.h
#ifndef MUDUO_BASE_COUNTDOWNLATCH_H
#define MUDUO_BASE_COUNTDOWNLATCH_H
#include <muduo/base/Condition.h>
#include <muduo/base/Mutex.h>
#include <boost/noncopyable.hpp>
namespace muduo
{
class CountDownLatch : boost::noncopyable
{
public:
explicit CountDownLatch(int count);
void wait();
void countDown();
int getCount() const;
private:
mutable MutexLock mutex_;//自己私有的,不是引用
Condition condition_;//自己私有的,不是引用
int count_;
};
}
#endif
//countDownLatch.cc
#include <muduo/base/CountDownLatch.h>
using namespace muduo;
CountDownLatch::CountDownLatch(int count)
: mutex_(),
condition_(mutex_),//mutex_是自己的,不是外边传进来,把自己的mutex_的引用传给自己的condition_
count_(count)
{
}
void CountDownLatch::wait()
{
MutexLockGuard lock(mutex_);
while(count_>0)
condition_.wait();
}
void CountDownLatch::countDown()
{
MutexLockGuard lock(mutex_);
--count_;
if(count_ == 0)
condition_.notifyAll();
}
int CountDownLatch::getCount() const
{
MutexLockGuard lock(mutex_);
return count_;
}
参考:c++教程网