前面有说道过互斥,互斥是异步的时候使用的,就是说,在资源的使用上,我用,你就不能用,我用完了你才可以用,没有逻辑上的相关性,而信号呢,是同步的时候用的,就是说这个步骤我做完了,需要下一个步骤开始了,我做完了通知你,你来处理下一步,有着逻辑上的相关性
声明:
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后,通知
}
上面着段代码在我的博客另外一篇文章中有。