造輪子之線程條件類的封裝

線程條件類的封裝

線程條件的基本操作

#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 本線程運行時間
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章