Boost logo

Boost Users :

From: Ben Hutchings (ben.hutchings_at_[hidden])
Date: 2004-02-18 06:51:21


Craig Rodrigues <rodrigc_at_[hidden]> wrote:
> It is possible to implement semaphore's with mutexes and
> condition variables. I looked at the source code for
> FreeBSD 5.2's implementation of semaphores to see how this was
> done:
>
>
http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/lib/libpthread/thre
ad/thr_sem.c
>
> I even took a whack at writing one based on Boost (it may be buggy):
>
> #include <boost/thread.hpp>
> #include <boost/thread/mutex.hpp>
>
> struct mysem {
> mysem(unsigned int count): count_(count) {}
>
> void post() {
> boost::mutex::scoped_lock l(sem_mutex_);
> ++count_;
> sem_cond_.notify_all();

notify_one() should be safe and more efficient here, because any of
the waiters can be satisfied by the change you have made. Use
notify_all() where waiters are waiting for different conditions on
the same condition variable. (I'm not sure I expressed that
exactly correctly - can anyone improve on that?)

> }
>
> void wait() {
> boost::mutex::scoped_lock l(sem_mutex_);
> for(;;) {
>
> if( count_ == 0 ) sem_cond_.wait(l);

This is wrong - you must always use while rather than if to test the
inverse of the condition you are waiting for because it is possible
that the condition is no longer true when wait() returns. (There is
also a function template for wait() that tests a predicate for you.)
It is even possible on some systems for wait() to return even though
no-one called notify_one() or notify_all().

> else { --count_; break; }
> }
> }
>
> private:
> unsigned int count_;
> boost::mutex sem_mutex_;
> boost::condition sem_cond_;
> };
>
>
> What kinds of things can go wrong if I use this class?
<snip>

The other potential problem I see is overflow of count_, but it is
exceedingly unlikely that you will be able to create enough threads
to cause that.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net