对于阻塞队列,当队列满时写线程阻塞,当队列为空时读线程阻塞。使用list为基础数据结构结合互斥锁来实现有大小限制的并发阻塞队列。
#include<algorithm>
#include<list>
using namespace std;
template <typename T>
class ThreadSafeContainer
{
public:
ThreadSafeContainer():maxSize_(1000)
{
pthread_mutex_init(&lock_,NULL);
pthread_cond_init(&rcond_,NULL);
pthread_cond_init(&wcond_,NULL);
//list_.size(maxSize_);
};
~ThreadSafeContainer()
{
pthread_mutex_destroy(&lock_);
pthread_cond_destroy(&rcond_);
pthread_cond_destroy(&wcond_);
};
void push(boost::shared_ptr<T> pelement)
{
pthread_mutex_lock(&lock_);
const bool was_empty = list_.empty();
while(list_.size() == maxSize_)
{
pthread_cond_wait(&wcond_,&lock_);
}
list_.push_back(pelement);
pthread_mutex_unlock(&lock_);
if(was_empty)
{
pthread_cond_broadcast(&rcond_);
}
}
boost::shared_ptr<T> pop()
{
pthread_mutex_lock(&lock_);
const bool was_full = (list_.size() == maxSize_);
while(list_.empty())
{
pthread_cond_wait(&rcond_,&lock_);
}
boost::shared_ptr<T> max = list_.front();
list_.pop_front();
pthread_mutex_unlock(&lock_);
if(was_full)
pthread_cond_broadcast(&wcond_);
return max;
}
int size()
{
return list_.size();
}
private:
list<boost::shared_ptr<T> > list_;
int maxSize_;
pthread_mutex_t lock_;
pthread_cond_t rcond_, wcond_;
};
这个阻塞队列有两个条件变量而不是一个。如果队列满了,写线程等待 _wcond
条件变量;读线程在从队列中取出数据之后需要通知所有线程。同样,如果队列是空的,读线程等待 _rcond
变量,写线程在把数据插入队列中之后向所有线程发送广播消息。如果在发送广播通知时没有线程在等待 _wcond
或 _rcond
,会发生什么?什么也不会发生;系统会忽略这些消息。还要注意,两个条件变量使用相同的互斥锁。
参考网页: http://www.ibm.com/developerworks/cn/aix/library/au-multithreaded_structures1/index.html