I’m implementing a concurrent_blocking_queue with minimal functions:
//a thin wrapper over std::queue
template<typename T>
class concurrent_blocking_queue
{
std::queue<T> m_internal_queue;
//...
public:
void add(T const & item);
T& remove();
bool empty();
};
I intend to use this for producer-consumer problem (I guess, it is where one uses such data structures?). But I’m stuck on one problem which is:
How to elegantly notify consumer when producer is done? How would the producer notify the queue when it is done? By calling a specifiic member function, say done()? Is throwing exception from the queue (i.e from remove function) a good idea?
I came across many examples, but all has infinite loop as if the producer will produce items forever. None discussed the issue of stopping condition, not even the wiki article.
My queues have usually used pointers (with an
std::auto_ptrin theinterface, to clearly indicate that the sender may no longer access the
pointer); for the most part, the queued objects were polymorphic, so
dynamic allocation and reference semantics were required anyway.
Otherwise, it shouldn’t be too difficult to add an “end of
file” flag to the queue. You’d need a special function on the
producer side (
close?) to set it (using exactly the same lockingprimitives as when you write to the queue), and the loop in the removal
function must wait for either something to be there, or the queue to be
closed. Of course, you’ll need to return a
Falliblevalue, so thatthe reader can know whether the read succeeded or not. Also, don’t
forget that in this case, you need a
notify_allto ensure that allprocesses waiting on the condition are awoken.
BTW: I don’t quite see how your interface is implementable. What does
the
T&returned byremoverefer to. Basically,removehas to besomething like:
Even without the
myIsDonecondition, you have to read the value into alocal variable before removing it from the queue, and you can’t return a
reference to a local variable.
For the rest: