線程條件類的封裝
線程條件的基本操作
#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 本線程運行時間