信号量Condition

前面有说道过互斥,互斥是异步的时候使用的,就是说,在资源的使用上,我用,你就不能用,我用完了你才可以用,没有逻辑上的相关性,而信号呢,是同步的时候用的,就是说这个步骤我做完了,需要下一个步骤开始了,我做完了通知你,你来处理下一步,有着逻辑上的相关性

声明:

class Condition : public NonCopyable {

public:

    /**

     * 构造函数

     */

    Condition(Mutex& mutex);

    

    /**

     * 释放函数

     */

    virtual ~Condition();

    

    /**

     * 等待, 会先释放锁再休眠, 被通知后再重新获取锁

     */

    void wait();

    

    /**

     * 尝试等待

     * @param timeout 超时绝对时间

     */

    bool tryWait(const TimeValue& timeout);

    

    /**

     * 通知一个等待线程

     */

    void signal();

    

    /**

     * 通知所有等待线程

     */

    void broadcast();

    

private:

    pthread_cond_t  _cond;

    Mutex&       _mutex;

};

实现:

Condition::Condition(Mutex& mutex) : _mutex(mutex) {

    int rc = pthread_cond_init(&_cond, 0);

    if (rc) {

        throw SynchException(rc);

    }

}

Condition::~Condition() {

    int rc = pthread_cond_destroy(&_cond);

    if (rc) {

        cerr << "Failed to destroy condition: " << SynchException::toString(rc) << endl;

    }

}

void Condition::wait() {

    int rc = pthread_cond_wait(&_cond, &(_mutex._mutex));

    if (rc) {

        throw SynchException(rc);

    }

}

bool Condition::tryWait(const TimeValue& timeout) {

    struct timespec absTime;

    absTime.tv_sec = static_cast<time_t>(timeout.toSeconds());

    absTime.tv_nsec = static_cast<long>((timeout.toMicroSeconds() % 1000000) * 1000);

    int rc = pthread_cond_timedwait(&_cond, &(_mutex._mutex), &absTime);

    if (rc && rc != ETIMEDOUT) {

        throw SynchException(rc);

    }

    return rc != ETIMEDOUT;

}

void Condition::signal() {

    int rc = pthread_cond_signal(&_cond);

    if (rc) {

        throw SynchException(rc);

    }

}

void Condition::broadcast() {

    int rc = pthread_cond_broadcast(&_cond);

    if (rc) {

        throw SynchException(rc);

    }

}

使用方法:

    void add(T inputItem) {

        while (_highWaterMark > 0 && _queue.size() >= _highWaterMark) {

            _highCond.wait();//队列元素过多,等待处理,信号等待

        }

        _queue.push_back(inputItem);

        _lowCond.signal();//队列元素push后,通知

    }

上面着段代码在我的博客另外一篇文章中有。

猜你喜欢

转载自konin.iteye.com/blog/2333383