muduo : Condition

https://github.com/chenshuo/muduo/blob/master/muduo/base/Condition.h

前面分析了互斥锁MutexLock的实现,这里分析一下条件变量Condition的实现。条件变量需要一个互斥锁来保护。关于互斥锁和条件变量的基本用法见这里。

成员变量

  MutexLock& mutex_;
  pthread_cond_t pcond_;

mutex_是个引用型变量,用来保护条件变量pcond_

构造/析构

  explicit Condition(MutexLock& mutex)
    : mutex_(mutex)
  {
    MCHECK(pthread_cond_init(&pcond_, NULL));
  }
  ~Condition()
  {
    MCHECK(pthread_cond_destroy(&pcond_));
  }

构造函数为explicit,必须显示调用。pcond_的初始化使用pthread_cond_init。析构时使用pthread_cond_destroy。都使用MCHECK来检测返回值是否是成功,失败时终止程序。

唤醒等待的线程

  void notify()
  {
    MCHECK(pthread_cond_signal(&pcond_)); // 通知一个
  }

  void notifyAll()
  {
    MCHECK(pthread_cond_broadcast(&pcond_)); // 通知所有
  }

进行等待

下面两个函数其实就是对pthread_cond_waitpthread_cond_timewait的wrapper。


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

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

wait()

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

在执行等待之前,使用UnassignGuard的构造函数将mutex_的holder清空(因为当前线程会休眠,暂时失去对mutex_的所有权)。接着调用pthread_cond_wait等待其他线程的通知。当其他某个线程调用了notify/notifyAll时,当前线程被唤醒,接着在wait返回时,UnassignGuard的析构函数自动将mutex_的holder设置为当前线程。

waitForSeconds()

// returns true if time out, false otherwise.
bool muduo::Condition::waitForSeconds(int seconds)
{
  struct timespec abstime;
  // FIXME: use CLOCK_MONOTONIC or CLOCK_MONOTONIC_RAW to prevent time rewind.
  clock_gettime(CLOCK_REALTIME, &abstime);
  abstime.tv_sec += seconds;
  MutexLock::UnassignGuard ug(mutex_);
  return ETIMEDOUT == pthread_cond_timedwait(&pcond_, mutex_.getPthreadMutex(), &abstime);
}

waitForSeconds行为与wait类似,只是多了个等待时间。

你可能感兴趣的:(muduo)