造轮子之线程条件类的封装

线程条件类的封装

线程条件的基本操作
#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 本线程运行时间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值