线程条件类的封装
线程条件的基本操作
#include <pthread.h>
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
线程条件类的定义
//线程信号异常类
struct YR_ThreadCond_Exception : public YR_Exception
{
YR_ThreadCond_Exception(const string &buffer) : YR_Exception(buffer){};
YR_ThreadCond_Exception(const string &buffer, int err) : YR_Exception(buffer, err){};
~YR_ThreadCond_Exception() throw() {};
};
//线程信号类,所有锁在上面等待信号发生
class YR_ThreadCond
{
public:
YR_ThreadCond();
~YR_ThreadCond();
/**
* @brief 发送信号, 等待在该条件上的一个线程会醒
*/
void signal();
/**
* @brief 等待在该条件的所有线程都会醒
*/
void broadcast();
/**
* @brief 获取绝对等待时间
*/
timespec abstime(int millsecond) const;
/**
* @brief 无限制等待.
*
* @param M
*/
template<typename Mutex>
void wait(const Mutex& mutex) const
{
int c = mutex.count();
int rc = pthread_cond_wait(&_cond, &mutex._mutex);
mutex.count(c);
if(rc != 0)
{
throw YR_ThreadCond_Exception("[YR_ThreadCond::wait] pthread_cond_wait error", errno);
}
}
/**
* @brief 等待时间.
*
* @param M
* @return bool, false表示超时, true:表示有事件来了
*/
template<typename Mutex>
bool timedWait(const Mutex& mutex, int millsecond) const
{
int c = mutex.count();
timespec ts = abstime(millsecond);
int rc = pthread_cond_timedwait(&_cond, &mutex._mutex, &ts);
mutex.count(c);
if(rc != 0)
{
if(rc != ETIMEDOUT) //如果超时
{
throw YR_ThreadCond_Exception("[YR_ThreadCond::timedWait] pthread_cond_timedwait error", errno);
}
return false;
}
return true;
}
protected:
YR_ThreadCond(const YR_ThreadCond&);
YR_ThreadCond& operator=(const YR_ThreadCond&);
private:
/**
* 线程条件
*/
mutable pthread_cond_t _cond;
};
实现
构造与析构
YR_ThreadCond::YR_ThreadCond()
{
int rc;
pthread_condattr_t attr; //定义条件属性对象
rc = pthread_condattr_init(&attr); //1. 初始化条件属性对象
if(rc != 0)
{
throw YR_ThreadCond_Exception("[YR_ThreadCond::YR_ThreadCond] pthread_condattr_init error", errno);
}
rc = pthread_cond_init(&_cond, &attr); //2. 初始化条件
if(rc != 0)
{
throw YR_ThreadCond_Exception("[YR_ThreadCond::YR_ThreadCond] pthread_cond_init error", errno);
}
rc = pthread_condattr_destroy(&attr); //3. 销毁条件属性对象
if(rc != 0)
{
throw YR_ThreadCond_Exception("[YR_ThreadCond::YR_ThreadCond] pthread_condattr_destroy error", errno);
}
}
YR_ThreadCond::~YR_ThreadCond()
{
int rc = 0;
rc = pthread_cond_destroy(&_cond);
if(rc != 0)
{
cerr << "[YR_ThreadCond::~YR_ThreadCond] pthread_cond_destroy error:" << string(strerror(rc)) << endl;
}
}
唤醒线程
void YR_ThreadCond::signal()
{
int rc = pthread_cond_signal(&_cond);
if(rc != 0)
{
throw YR_ThreadCond_Exception("[YR_ThreadCond::signal] pthread_cond_signal error", errno);
}
}
void YR_ThreadCond::broadcast()
{
int rc = pthread_cond_broadcast(&_cond);
if(rc != 0)
{
throw YR_ThreadCond_Exception("[YR_ThreadCond::broadcast] pthread_cond_broadcast error", errno);
}
}
获取绝对等待时间(精度为纳秒)
timespec YR_ThreadCond::abstime( int millsecond) const
{
struct timeval tv;
gettimeofday(&tv, 0); //时间操作将会被封装,如下注释
//TC_TimeProvider::getInstance()->getNow(&tv);
//it 精度为微秒
int64_t it = tv.tv_sec * (int64_t)1000000 + tv.tv_usec + (int64_t)millsecond * 1000;
tv.tv_sec = it / (int64_t)1000000;
tv.tv_usec = it % (int64_t)1000000;
timespec ts;
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = tv.tv_usec * 1000;
return ts;
}
//注:timeval的最高精度为微秒,timespec的最高精度为纳秒
// timeval由gettimeofday()获取系统时间
// timespec由clock_gettime(clockid_t, struct timespec *)获取特定时间
// CLOCK_REALTIME 统当前时间,从1970年1.1日算起
// CLOCK_MONOTONIC 系统的启动时间,不能被设置
// CLOCK_PROCESS_CPUTIME_ID 本进程运行时间
// CLOCK_THREAD_CPUTIME_ID 本线程运行时间