[Muduo网络库源码分析] (6) base/Mutex.h_互斥锁操作

互斥锁操作

功能:封装对互斥锁的操作


知识点:

  • MCHECK()宏的实现
#define MCHECK(ret) ({ __typeof__ (ret) errnum = (ret);         \
                       if (__builtin_expect(errnum != 0, 0))    \
                         __assert_perror_fail (errnum, __FILE__, __LINE__, __func__);})
  • 线程与锁的对应关系

用途:

可用于多线程互斥锁的操作

亮点程序:

//对锁进行解锁,加锁操作
class MutexLockGuard : boost::noncopyable
{
 public:
  explicit MutexLockGuard(MutexLock& mutex)
    : mutex_(mutex)
  {
    mutex_.lock();
  }

  ~MutexLockGuard()
  {
    mutex_.unlock();
  }

 private:

  MutexLock& mutex_;
};

上述代码在使用过程中非常方便,其可以对作用域内的内容上锁,并实现自动解锁

{
    MutexLockGuard mu = MutexLockGuard(mutex_)
    ...
}

代码及分析:

Mutex.h

// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#ifndef MUDUO_BASE_MUTEX_H
#define MUDUO_BASE_MUTEX_H

#include 
#include 
#include 
#include 

#ifdef CHECK_PTHREAD_RETURN_VALUE

#ifdef NDEBUG
//用C++编译器统一处理
__BEGIN_DECLS
extern void __assert_perror_fail (int errnum,
                                  const char *file,
                                  unsigned int line,
                                  const char *function)
    //无返回值
    __THROW __attribute__ ((__noreturn__));
__END_DECLS
#endif
//检查是否出错 ,__typeof__定义与ret类型相同的errnum,大多数情况下不执行if语句
#define MCHECK(ret) ({ __typeof__ (ret) errnum = (ret);         \
                       if (__builtin_expect(errnum != 0, 0))    \
                         __assert_perror_fail (errnum, __FILE__, __LINE__, __func__);})

#else  // CHECK_PTHREAD_RETURN_VALUE

#define MCHECK(ret) ({ __typeof__ (ret) errnum = (ret);         \
                       assert(errnum == 0); (void) errnum;})

#endif // CHECK_PTHREAD_RETURN_VALUE

namespace muduo
{

// Use as data member of a class, eg.
//
// class Foo
// {
//  public:
//   int size() const;
//
//  private:
//   mutable MutexLock mutex_;
//   std::vector data_; // GUARDED BY mutex_
// };
class MutexLock : boost::noncopyable
{
 public:
  //构造函数,初始化线程ID,初始化锁
  MutexLock()
    : holder_(0)
  {
    MCHECK(pthread_mutex_init(&mutex_, NULL));
  }
  //析构函数,销毁锁
  ~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();
  }

  //如果不是作用于当前线程,则退出
  void assertLocked() const
  {
    assert(isLockedByThisThread());
  }

  // internal usage
  //上锁,并存储上锁的线程ID
  void lock()
  {
    MCHECK(pthread_mutex_lock(&mutex_));
    assignHolder();
  }
  //解锁,并置当前线程ID标记为0
  void unlock()
  {
    unassignHolder();
    MCHECK(pthread_mutex_unlock(&mutex_));
  }
  //返回锁地址
  pthread_mutex_t* getPthreadMutex() /* non-const */
  {
    return &mutex_;
  }

 private:
  friend class Condition;
  //对加锁的线程进行线程ID的改变
  class UnassignGuard : boost::noncopyable
  {
   public:
    UnassignGuard(MutexLock& owner)
      : owner_(owner)
    {
      owner_.unassignHolder();
    }

    ~UnassignGuard()
    {
      owner_.assignHolder();
    }

   private:
    MutexLock& owner_;
  };

  //对holder_置零
  void unassignHolder()
  {
    holder_ = 0;
  }

  //给holder_赋值为当前线程ID
  void assignHolder()
  {
    holder_ = CurrentThread::tid();
  }

  pthread_mutex_t mutex_;//互斥锁
  pid_t holder_;//线程ID
};

// Use as a stack variable, eg.
// int Foo::size() const
// {
//   MutexLockGuard lock(mutex_);
//   return data_.size();
// }

//对锁进行解锁,加锁操作
class MutexLockGuard : boost::noncopyable
{
 public:
  explicit MutexLockGuard(MutexLock& mutex)
    : mutex_(mutex)
  {
    mutex_.lock();
  }

  ~MutexLockGuard()
  {
    mutex_.unlock();
  }

 private:

  MutexLock& mutex_;
};

}

// Prevent misuse like:
// MutexLockGuard(mutex_);
// A tempory object doesn't hold the lock for long!
#define MutexLockGuard(x) error "Missing guard object name"

#endif  // MUDUO_BASE_MUTEX_H

你可能感兴趣的:(Muduo网络库,Muduo网络库源码分析与实践)