Boost logo

Boost :

From: williamkempf_at_[hidden]
Date: 2001-08-13 07:34:09


--- In boost_at_y..., flameframe_at_h... wrote:
> --- In boost_at_y..., williamkempf_at_h... wrote:
>
>
> > Condition variables *MUST* be used in conjunction with a mutex
> which
> > is locked before the wait, unlocked during the wait, and locked
> again
> > after the wait in a thread safe manner. Condition variables use
an
> > interface that makes this hard to do wrong (with Boost.Threads it
> > becomes impossible). Events *MUST NOT* be used in conjunction
with
> a
> > mutex, and if you attempt to you wind up with race conditions.
>
> Why?
> Probably I am not an expert here but I often use such a
> conjunction w/o any problem. What means '*MUST NOT*'? I have
followed
> the discussion for a while and see that most of arguments are in
> declarative form. Where are the proofs?

We've given pseudo code that demonstrates the race conditions on two
occasions. After the wait on the event you must re-lock the mutex in
order to manipulate the shared data, but between these two
instructions another thread may have done some operation that
invalidates the reason the event was signalled. There are *MUCH*
better explanations and examples in the texts referenced earlier in
this thread. This whole topic is a tad too complicated to fully
cover in e-mail, so I won't even try. Instead I'll just ask that you
read the papers on this topic from earlier posts.

> > Nothing in their interface can prevent this misuse, and
> unfortunately
> > most programmers don't understand this danger. So events are
> > dangerous in comparison to condition variables.
>
> Here is a quote from Boost.Thread docs about CV wait:
> {{ Danger: This version should always be used within a loop
checking
> that the state logically associated with the condition has become
> true. Without the loop, race conditions can ensue due to
> possible "spurious wake ups". }}
> And here is a comment from source code
> {{// 23 May 01 WEKEMPF Removed "duration" timed_waits, as they
are
> too difficult to use with spurious wakeups.
> }}
>
> //Sorry if these quotes are out of date or not appropriate out of
> context.
>
> Could anything with word "spurious" w/o proofs be
> declared as less dangerous and more easy to use?

Spurious wake ups are a necessary evil, but in reality they occur
extremely infrequently. Once you've wrapped the call to wait in a
while loop (or used the predicate version of wait) then you've got no
danger from spurious wakeups. The CV also guarantees that you don't
have any danger from race conditions or deadlock. So, yes, they can
be declared as less dangerous.
 
> > Further, there are
> > very few designs in which an event is the optimal synchronization
> > object to use, and even in those rare cases a condition variable
> can
> > easily be used instead, while the converse isn't true.
>
> Hmm, 'converse isn't true'. Can you show an example based on CV
that
> can't be implemented with (event/mutex/semafore+multiple waits as
it
> is in Win32) model? I believe this combination is a bit more low-
> level concept than with CV, and therefore can be used inplace. It
> looks like Or/And/Not-based logic against Xor/And/Not-based.

I don't know what you mean by "(event/mutex/semafore+multiple waits
as it is in Win32)". The classic monitor, as it's given in the
Boost.Threads documentation, is impossible to code with out race
conditions using only an event and a mutex. Throw in the semaphore
(actually, two of them) and then it can be done, but the code needed
to do so is non-trivial and hard to get right. All that a CV does is
wrap this non-trivial code into a trivial interface.
 
> > That said, those rare cases where an event is optimal are valid...
> >
> > > than more specific synchronisation techniques. Would you agree?
> > > And, more for Bill: is there anything preventing an
> > > event synchronisation subsystem being added to the library?
> >
> > No, event's can be trivially added to Boost.Threads, using the
> native
> > event objects in Win32 and condition variables in POSIX.
However,
> > because of the reasons I gave above, this is not an extension
that
> > I'll be making before submission. If people find a legitimate
need
> > for them later we can discuss the pros and cons more carefully
and
> > add events if we then deem them to be needed.
>
> There are a lot of existing code using events. Would you expect
them
> to change their way of thinking in a moment?

In a moment, know. But once they understand the concept, yes.
Again, I'm a Win32 programmer who's been doing threaded programming
on that platform for years. I didn't have any knowledge of POSIX at
all when I first ran across this issue with events. I've been bitten
by race conditions leading to deadlocks because of the use of events
more times then I care to recall. Once a programmer sees the race
conditions in his own code, he'll want to change immediately.

Bill Kempf


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk