0
点赞
收藏
分享

微信扫一扫

【muduo/base】线程同步类

点亮自己的那盏灯 2022-01-13 阅读 25

前言

muduo库也对线程同步原语封装了一下,为下面三个类:
(1) MutexLock (2)Condition (3) CountDownLatch
我将简化类,或以伪代码的形式作为讲解

mutex类

简化后的代码

class MutexLock : noncopyable
{
 public:
  MutexLock()
  {
  	//pthread_mutex_init 系统调用 初始化一个锁
    MCHECK(pthread_mutex_init(&mutex_, NULL));
  }

  ~MutexLock()
  {
  	//pthread_mutex_destroy 系统调用 销毁锁
    MCHECK(pthread_mutex_destroy(&mutex_));
  }

  void lock()
  {
 	 //pthread_mutex_lock系统调用 加锁
    MCHECK(pthread_mutex_lock(&mutex_));
  }

  void unlock()
  {
  	//pthread_mutex_lock系统调用 解锁
    MCHECK(pthread_mutex_unlock(&mutex_));
  }

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

 private:
  friend class Condition;
  pthread_mutex_t mutex_;
};

Condition

class Condition : noncopyable
{
 public:
  explicit Condition(MutexLock& mutex)
    : mutex_(mutex)
  {
  	//创建条件变量
    MCHECK(pthread_cond_init(&pcond_, NULL));
  }

  ~Condition()
  {
  	//销毁条件变量
    MCHECK(pthread_cond_destroy(&pcond_));
  }

  void wait()
  {
  	//条件变量阻塞,所有使用该mutex_锁的线程会进入一个等待队列中,暂时无法获取锁
    MCHECK(pthread_cond_wait(&pcond_, mutex_.getPthreadMutex()));
  }
  
  void notify()
  {
  	//条件变量解除堵塞,通知堵塞队列中一个线程获取锁
    MCHECK(pthread_cond_signal(&pcond_));
  }

  void notifyAll()
  {
  	//条件变量解除堵塞,通知堵塞队列中所有线程去获取锁(注意锁争用)
    MCHECK(pthread_cond_broadcast(&pcond_));
  }

 private:
  MutexLock& mutex_;
  pthread_cond_t pcond_;
};

CountDownLatch类

头文件代码

class CountDownLatch : noncopyable
{
 public:

  explicit CountDownLatch(int count);//避免传入bool等意义不明的参数,禁止隐式转换

  void wait();//堵塞直到计数减到0

  void countDown();

  int getCount() const;

 private:
  mutable MutexLock mutex_;
  Condition condition_ GUARDED_BY(mutex_);
  int count_ GUARDED_BY(mutex_);//确保对count_ 的操作是原子的
};

构造函数为什么要exexplicit修饰

mutable作用是什么

源代码

CountDownLatch::CountDownLatch(int count)
    : mutex_(),
      condition_(mutex_),
      count_(count)
{
}

void CountDownLatch::wait()
{
  MutexLockGuard lock(mutex_);
  //必须用循环,堵塞该函数调用之后的逻辑,count_ == 0时,解除堵塞
  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_;
}

分析

void func(){
	//创建CountDownLatch对象,设count_为线程数n
	//创建n个线程,将CountDownLatch的指针作为线程传入参数传进去,
		线程函数体中调用CountDownLatch->CountDownLatch方法,是count_--
	//CountDownLatch.wait() 
	//其他逻辑
}

当n个线程运行起来后,CountDownLatch.wait()才会解除堵塞,进而执行后面的逻辑。

注意点1:

注意点2:

void CountDownLatch::countDown()
{
 MutexLockGuard lock(mutex_);
 --count_;
 if (count_ == 0)
 {
   condition_.notifyAll();
 }
}
举报

相关推荐

0 条评论