muduo源码分析:互斥锁、条件变量、倒计时封装

来源:互联网 发布:xp系统终极优化 编辑:程序博客网 时间:2024/05/22 06:29

互斥锁封装: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,否则返回falsebool 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类型,因为 getCount成员函数是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++教程网

           muduo网络库

           linux多线程服务器端编程》.陈硕





0 0