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_;
}