muduo的Mutex类剖析

来源:互联网 发布:列式数据库 olap 编辑:程序博客网 时间:2024/05/22 08:04

muduo的mutex_lock_guard()就是利用C++的RAII机制,完成互斥锁锁的自动加锁,解锁操作,解放双手。我们只需要用一堆大括号的控制互斥锁的范围就可以了。

RAII(Resource Acquisition Is Initialization),也称为“资源获取就是初始化”,是C++语言的一种管理资源、避免泄漏的惯用法。C++标准保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。简单的说,RAII 的做法是使用一个对象,在其构造时获取资源,在对象生命期控制对资源的访问使之始终保持有效,最后在对象析构的时候释放资源。


它有两个主要成员,MutexLock类和MutexlockGuard类。这两个类之间的关系仅仅只是关联关系,MutexLockGuard中使用了MutexLock中的

lock()和unlock()方法。它们之间不存在整体与局部的关系,如果存在整体与局部的关系,那就是聚合关系。如果不仅仅存在整体与局部的关系,并且还负责这个对象的生存期,那么就是组合关系


它们的接口如图:





代码加注释如下:

class MutexLock : boost::noncopyable{ public:  MutexLock()    : holder_(0)  {    MCHECK(pthread_mutex_init(&mutex_, NULL));   //MEMCHECK是多retval的检测,相当于assert,下同  }  ~MutexLock()  {    assert(holder_ == 0);    //只有在没有被其它线程持有的情况下才可以析构    MCHECK(pthread_mutex_destroy(&mutex_));  }  // must be called when locked, i.e. for assertion  bool isLockedByThisThread() const   //是否被本线程上锁  {    return holder_ == CurrentThread::tid();  //返回id,通过systemcall + cache方式  }  void assertLocked() const  {    assert(isLockedByThisThread());  }  // internal usage  void lock()  {    MCHECK(pthread_mutex_lock(&mutex_));    assignHolder();     //赋值,赋上tid  }          //lock()和unlock()函数中两个语句顺序都不能乱  void unlock()  {    unassignHolder();   //首先要清零    MCHECK(pthread_mutex_unlock(&mutex_));  }  pthread_mutex_t* getPthreadMutex() /* non-const */  {    return &mutex_;  } private:  friend class Condition;  class UnassignGuard : boost::noncopyable    //取消赋值  {   public:    UnassignGuard(MutexLock& owner)      : owner_(owner)    {      owner_.unassignHolder();    }    ~UnassignGuard()    {      owner_.assignHolder();    }   private:    MutexLock& owner_;  };  void unassignHolder()  {    holder_ = 0;  }  void assignHolder()  {    holder_ = CurrentThread::tid();  }  pthread_mutex_t mutex_;  pid_t holder_;};// Use as a stack variable, eg.// int Foo::size() const// {//   MutexLockGuard lock(mutex_);//   return data_.size();// }class MutexLockGuard : boost::noncopyable   //我们用这个类,就是在利用C++的RAII机制,让锁在作用域内全自动化{ public:  explicit MutexLockGuard(MutexLock& mutex)      : mutex_(mutex)  {    mutex_.lock();  }  ~MutexLockGuard()  {    mutex_.unlock();  } private:  MutexLock& mutex_;    //为甚么要使用引用?因为他们仅仅是关联关系,使用引用不会导致MutexLock对象的销毁!!!};}// Prevent misuse like:// MutexLockGuard(mutex_);// A tempory object doesn't hold the lock for long!#define MutexLockGuard(x) error "Missing guard object name"  //定义一个宏,防止定义一个无名临时MutexLockGuard对象,因为它不能够长时间拥有锁

0 0