Недавно я сделал нечто подобное, хотя мой использует очередь STL. Посмотрим, сможете ли вы выбрать из моей реализации. Как говорит wilx , нужно дождаться состояния. Моя реализация имеет максимальный предел для элементов в очереди, и я использую это для ожидания освобождения мьютекса / охранника.
Первоначально я делал это в Windows, имея в виду возможность использования разделов Mutex или Critical, поэтому параметр шаблона можно удалить и использовать boost::mutex
напрямую, если он упрощает его для вас.
#include <queue>
#include "Message.h"
#include <boost/thread/locks.hpp>
#include <boost/thread/condition.hpp>
template <typename T> class Queue : private boost::noncopyable
{
public:
// constructor binds the condition object to the Q mutex
Queue(T & mutex, size_t max_size) : m_max_size(max_size), m_mutex(mutex){}
// writes messages to end of Q
void put(const Message & msg)
{
// Lock mutex to ensure exclusive access to Q
boost::unique_lock<T> guard(m_mutex);
// while Q is full, sleep waiting until something is taken off of it
while (m_queue.size() == m_max_size)
{
cond.wait(guard);
}
// ok, room on the queue.
// Add the message to the queue
m_queue.push(msg);
// Indicate so data can be ready from Q
cond.notify_one();
}
// Read message from front of Q. Message is removed from the Q
Message get(void)
{
// Lock mutex to ensure exclusive access to Q
boost::unique_lock<T> guard(m_mutex);
// If Q is empty, sleep waiting for something to be put onto it
while (m_queue.empty())
{
cond.wait(guard);
}
// Q not empty anymore, read the value
Message msg = m_queue.front();
// Remove it from the queue
m_queue.pop();
// Signal so more data can be added to Q
cond.notify_one();
return msg;
}
size_t max_size(void) const
{
return m_max_size;
}
private:
const size_t m_max_size;
T & m_mutex;
std::queue<Message> m_queue;
boost::condition_variable_any cond;
};
Таким образом, вы можете разделить очередь между производителем / потребителем. Пример использования
boost::mutex mutex;
Queue<boost::mutex> q(mutex, 100);
boost::thread_group threads;
threads.create_thread(Producer<boost::mutex>(q));
threads.create_thread(Consumer<boost::mutex>(q));
threads.join_all();
С определением производителя / потребителя, как указано ниже
template <typename T> class Producer
{
public:
// Queue passed in
explicit Producer(Queue<T> &q) : m_queue(q) {}
void operator()()
{
}
}