base5. MutexLock和MutexLockGuard互斥量类、Condition条件变量类、CountDownLatch倒计时门栓类(计数类)

MutexLock类图
在这里插入图片描述
数据成员:

pthread_mutex_t mutex_:pthread_mutex_t类型的线程互斥量mutex_
pid_t holder_:holder_用于保存锁拥有者的线程tid

成员函数:

MutexLock():构造函数,初始化mutex_
~MutexLock():析构函数,销毁mutex_
bool isLockedByThisThread():判断当前线程是否拥有该锁
void assertLocked():断言当前线程拥有该锁
void lock():加锁,并将holder_设置为被加锁线程的tid
void unlock():解锁,并将holder_设置为0
pthread_mutex_t* getPthreadMutex():获取mutex_数据成员

MutexLockGuard类图
在这里插入图片描述
MutexLockGuard通过RAII方式管理MutexLock资源:构造MutexLockGuard对象时,取得mutex_锁;释放对象时,释放mutex_锁。

数据成员:

MutexLock& mutex_:一个引用类型的MutexLock对象,MutexLock和MutexLockGuard是关联关系

成员函数:
explicit MutexLockGuard(MutexLock& mutex):构造函数,获取mutex_并加锁
~MutexLockGuard():析构函数,释放mutex_并解锁

Mutex.h

#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());
  }

  // internal usage
  //加锁
  void lock()
  {
    pthread_mutex_lock(&mutex_);
    holder_ = CurrentThread::tid();
  }
  //解锁
  void unlock()
  {
    holder_ = 0;
    pthread_mutex_unlock(&mutex_);
  }
  //获取mutex_数据成员
  pthread_mutex_t* getPthreadMutex() /* non-const */
  {
    return &mutex_;
  }

 private:
  //pthread_mutex_t类型的线程互斥量mutex_
  pthread_mutex_t mutex_;
  //pid_t类型的锁拥有者的线程tid
  pid_t holder_;
};
//MutexLockGuard更常用,自动对MutexLock对象加锁和解锁
class MutexLockGuard : boost::noncopyable
{
 public:
  //构造函数中获取锁
  explicit MutexLockGuard(MutexLock& mutex)
    : mutex_(mutex)
  {
    mutex_.lock();
  }
  //析构函数中释放锁
  ~MutexLockGuard()
  {
    mutex_.unlock();
  }

 private:
  //一个引用类型的MutexLock对象,两个类是关联关系
  MutexLock& mutex_;
};

}

// Prevent misuse like:
// MutexLockGuard(mutex_);
// A tempory object doesn't hold the lock for long!

//这个宏是防止MutexLockGuard(mutex_)的用法
#define MutexLockGuard(x) error "Missing guard object name"

#endif  // MUDUO_BASE_MUTEX_H

Condition类图
在这里插入图片描述
数据成员:

MutexLock& mutex_:一个MutexLock类型的引用对象mutex_
pthread_cond_t pcond_:一个pthread_cond_t类型的条件变量pcond_

成员函数:
explicit Condition(MutexLock& mutex):构造函数中初始化条件变量pcond_
~Condition():析构函数中销毁条件变量pcond_
void wait():等待函数
bool waitForSeconds(int seconds):等待一定时间,超过这个时间之后就超时
void notify():调用signal函数,通知一个处于阻塞状态的线程
void notifyAll():调用broadcast函数,通知所有处于阻塞状态的线程

Condition.h

#ifndef MUDUO_BASE_CONDITION_H
#define MUDUO_BASE_CONDITION_H

#include <muduo/base/Mutex.h>

#include <boost/noncopyable.hpp>
#include <pthread.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());
  }
  //等待一定时间,超过这个时间之后就超时
  // returns true if time out, false otherwise.
  bool waitForSeconds(int seconds);
  //调用signal函数,通知一个处于阻塞状态的线程
  void notify()
  {
    pthread_cond_signal(&pcond_);
  }
  //调用broadcast函数,通知所有处于阻塞状态的线程
  void notifyAll()
  {
    pthread_cond_broadcast(&pcond_);
  }

 private:
  //一个MutexLock类型的引用对象
  MutexLock& mutex_;
  //一个pthread_cond_t类型的条件变量
  pthread_cond_t pcond_;
};

}
#endif  // MUDUO_BASE_CONDITION_H

Condition.cc

#include <muduo/base/Condition.h>

#include <errno.h>

// returns true if time out, false otherwise.
bool muduo::Condition::waitForSeconds(int seconds)
{
  struct timespec abstime;
  clock_gettime(CLOCK_REALTIME, &abstime);
  abstime.tv_sec += seconds;
  return ETIMEDOUT == pthread_cond_timedwait(&pcond_, mutex_.getPthreadMutex(), &abstime);
}


CountDownLatch类图
在这里插入图片描述
对条件变量的封装类,既可以用于所有子线程等待主线程发起 “起跑” ,也可以用于主线程等待子线程初始化完毕才开始工作。

数据成员:

mutable MutexLock mutex_:一个MutexLock锁对象,并且这个对象声明为mutable,说明其可在const函数中被修改
Condition condition_:一个Condition条件变量对象condition_
int count_:计数器count_

成员函数:

explicit CountDownLatch(int count):构造函数,用count初始化count_
void wait():等待函数,若count_>0,等待
void countDown():计数器count_减一,计数器count_==0时,唤醒所有线程
int getCount() const:获取计数器count_的值

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);
  //等待函数,count_>0,等待
  void wait();
  //计数器count_减一,计数器count_==0时,唤醒所有线程
  void countDown();
  //获取计数器count_的值
  int getCount() const;

 private:
  //一个MutexLock锁对象,并且这个对象声明为mutable,说明其可在const函数中被修改
  mutable MutexLock mutex_;
  //一个Condition条件变量对象
  Condition condition_;
  //计数器
  int count_;
};

}
#endif  // MUDUO_BASE_COUNTDOWNLATCH_H

CountDownLatch.cc

#include <muduo/base/CountDownLatch.h>

using namespace muduo;

CountDownLatch::CountDownLatch(int count)
  : mutex_(),
    condition_(mutex_),
    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_;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值