muduo的Mutex类剖析

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

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


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

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


它们的接口如图:

muduo的Mutex类剖析_第1张图片


muduo的Mutex类剖析_第2张图片


代码加注释如下:

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对象,因为它不能够长时间拥有锁

你可能感兴趣的:(Muduo源码剖析,muduo源码剖析)