Amerio wrote:
Looks almost correct. But as you likely will have multiple waiters, I suggest using m_cond_.notify_all() instead.
This one I don't understand. When my sem is incremented by one, I want to wake up only one reader (as there is only one new entry to be read). Why would I want to wake up all of them ? As I see it, one post means one new entry exactly.
Ooops, of course you can't understand, because my answer was wrong in this respect. Sorry for this. It was kind of lazyness which led me to this answer. It cannot happen, that the counter increases while you are waiting since you are notifying on each increment. So your example seems correct to me.
I also recommend to look at the "condvar" example of boost.thread, which shows a simple queue implementation (albeit for single reader/writer).
I find their example a little tricky. I specially miss a multiple reader/writer example. Moreover, the loop around the cond.wait() is tricky at first and should get more attention. In my own example, I was also wondering if I got the "while" loop right : void wait() { boost::mutex::scoped_lock lock(m_mutex); while ( m_count==0 ) m_cond.wait( lock ); // is cond test ok ? --m_count; }
Hopefully beeing more careful now: Using locks and condvars this way is exactly the recommended usage pattern. This also takes care of so called 'spurious' wakeups which might take place dependant on the implementation of the wait. This also is the reason why notify_all would not have done harm other than beeing of slower performance. Yet another tought: When you have returned from your wait function you will need another lock to access your queue in order to retrieve an entry. On the other hand when returning from m_cond.wait you are the holder of lock. So if you use the m_mutex also to protect your queue you save one locking operation. Consider doing away with the semaphore and integrate the condvar, mutex pair into your queue. Think of a semaphore only beeing a special case of (condvar,mutex,counter) triple. Roland