我尝试实现阻塞队列。主要部分如下(这是一种教育任务)
template <typename T>
class Blocking_queue
{
public:
std::queue<T> _queue;
boost::mutex _mutex;
boost::condition_variable _cvar;
void Put(T& object);
T Get();
void Disable()
};
template<typename T>
void Blocking_queue::Put(T& object)
{
boost::mutex::scoped_lock lock(_mutex);
_queue.push(T);
lock.unlock();
_cvar.notify_one();
}
template<typename T>
T Blocking_queue::Get()
{
boost::mutex::scoped_lock lock(_mutex);
while(_queue.empty())
{
_cvar.wait(_mutex);
}
T last_el = _queue.front();
_queue.pop();
return last_el;
}
template<typename T>
void Blocking_queue::Disable()
{
}
而且我需要实现一个Disable()函数来“释放”所有正在等待的线程(如任务中所写)。问题是我不完全理解这个术语中的“释放”是什么意思,以及我应该采用什么方法。所以我的想法如下:当调用Disable()时,我们应该在该位置(在循环内)为当前线程调用某种方法。
while(_queue.empty())
{
//here
_cvar.wait(_mutex);
}
哪个会释放当前线程,对吗?谢谢。
最佳答案
“释放所有正在等待的线程”是一项几乎没有用的操作。您想对该操作做什么?
有用的是关闭队列,因此等待队列中的每个线程都将被解除阻塞,并且将要调用Get()的每个线程都将立即返回。要实现这种行为,只需在队列中添加一个关闭标志,然后等待“不为空或关闭”:
template<typename T>
void Blocking_queue::Disable()
{
boost::mutex::scoped_lock lock(_mutex);
_shutdown = true;
_cvar.notify_all()
}
为了指示没有数据,可以向Get()的调用者返回带有附加 bool(boolean) 值的对或抛出特殊异常。无法返回空值,因为并非对于所有类型T都存在空值。
template<typename T>
std::pair< bool, T > Blocking_queue::Get()
{
boost::mutex::scoped_lock lock(_mutex);
while (_queue.empty() && !_shutdown )
_cvar.wait(_mutex);
if ( _shutdown )
return std::make_pair( false, T() );
T last_el = _queue.front();
_queue.pop();
return std::make_pair( true, last_el );
}