【muduo源码分析 】 MutexLock和MutexLockGuard封装

       MutexLock 封装临界区(critical section),这是一个简单的资源类,用RAII 手法[CCS,条款13] 封装互斥器的创建与销毁。临界区在Windows 上是struct CRITICAL_SECTION,是可重入的;在Linux 下是pthread_mutex_t,默认是不可重入的。MutexLock 一般是别的class 的数据成员。

       MutexLockGuard 封装临界区的进入和退出,即加锁和解锁。MutexLockGuard 一般是个栈上对象,它的作用域刚好等于临界区域。

class noncopyable
{
 public:
  noncopyable(const noncopyable&) = delete;   //禁止生成
  void operator=(const noncopyable&) = delete;

 protected:
  noncopyable() = default;
  ~noncopyable() = default;
};


class MutexLock : noncopyable
{
 public:
  MutexLock()
  {
     pthread_mutex_init(&mutex_, NULL);   //初始化互斥量
  }

  ~MutexLock()
  {
     pthread_mutex_destroy(&mutex_);      //销毁互斥量
  }


  // internal usage

  void lock() 
  {
     pthread_mutex_lock(&mutex_);
  }

  void unlock() 
  {
     pthread_mutex_unlock(&mutex_);
  }

  pthread_mutex_t* getPthreadMutex() /* non-const */
  {
     return &mutex_;
  }

  pthread_mutex_t mutex_;

};

class  MutexLockGuard : noncopyable
{
 public:
  explicit MutexLockGuard(MutexLock& mutex) 
    : mutex_(mutex)
  {
      mutex_.lock();                       //调用互斥量上锁
  }

  ~MutexLockGuard() 
  {
      mutex_.unlock();                    //调用互斥量解锁
  }

 private:

  MutexLock& mutex_;
};

 

class Condition : noncopyable
{
 public:
  explicit Condition(MutexLock& mutex)
    : mutex_(mutex)
  {
     pthread_cond_init(&pcond_, NULL);
  }

  ~Condition()
  {
     pthread_cond_destroy(&pcond_);
  }

  void wait()
  {
     MutexLock::UnassignGuard ug(mutex_);
     pthread_cond_wait(&pcond_, mutex_.getPthreadMutex());
  }

  // returns true if time out, false otherwise.
  bool waitForSeconds(double seconds);

  void notify()
  {
     pthread_cond_signal(&pcond_);
  }

  void notifyAll()
  {
     pthread_cond_broadcast(&pcond_);
  }

 private:
    MutexLock& mutex_;
    pthread_cond_t pcond_;
};

实例:

      编写单个的线程安全的 class 不算太难,只需用同步原语保护其内部状态。例如 下面这个简单的计数器类 Counter:

// A thread-safe counter
class Counter : boost::noncopyable
{
// copy-ctor and assignment should be private by default for a class.
public:

    Counter() : value_(0) {}
    int64_t value() const;
    int64_t getAndIncrease();
private:
    int64_t value_;
    mutable MutexLock mutex_;
};

int64_t Counter::value() const
{
    MutexLockGuard lock(mutex_); // lock 的析构会晚于返回对象的构造,
    return value_;              // 因此有效地保护了这个共享数据。
}

int64_t Counter::getAndIncrease()
{
    MutexLockGuard lock(mutex_);  //返回对象前,lock的析构函数会自动调用释放互斥锁函数
    int64_t ret = value_++;
    return ret;
}
//

总结:由上代码分析知,MutexLockGuard类解决了自动释放互斥量的问题,可有效避免人为失误的问题。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值