Я пытаюсь реализовать блокировку очереди. основные части следующие (это своего рода учебное задание)
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 или выдать специальное исключение. Нет никакого способа вернуть ноль, поскольку не для всех типов 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 );
}
Других решений пока нет …