Boost logo

Boost :

From: Sean Kelly (sean_at_[hidden])
Date: 2004-01-26 12:21:15


> At 12:38 AM 1/26/2004, Sean Kelly wrote:
>
> What is vague about "event operations force the programmer to be aware of
> the relative speeds of the sending and receiving processes"?
>
> In your sample program, you have made assumptions about the relative
> speeds
> that add_message() and process_msgs() work. (It is a little hard to know
> exactly what assumptions you have made without knowing the details of how
> process_msgs() uses sync.) If those assumptions are ever violated,
> add_message() will become unresponsive or events will get dropped.

Please note that all access to the message queue (both read and write) was
wrapped in a mutex. Unless there's something I don't know about mutexes,
there should be no issue with contention for the message queue. One
important thing to note however, my sample code all assumed a single
thread waiting on the event object (ie. a single consumer). This is why
the manual reset is not problematic. I should have stated this up front.

> Now it might be possible for the event object to detect a call to
> event::add() while there is still an event pending, and throw an
> exception.
> That would at least change a dropped event from a silent error into a
> noisy
> error. But that still doesn't solve the underlying design flaw of events
> that they are dependent on relative speeds of producers and consumers.

I suppose I should have included the code for process_msgs as well. It
would be something like this:

void process msgs() {
    // begin loop
    // acquire mutex
    // if queue is empty then release mutex and return
    // pop a message off the queue
    // release mutex
    // process message
    // continue loop
}

If the producer is faster then the consumer will never leave the function.
 If the consumer is faster then it will wait on the event until it is
notified that the queue contains more messages.

> That's the scary thing about events. A program runs OK for years, and then
> something changes the relative thread timings, like if the program gets
> moved from a single-cpu machine to a multi-cpu machine, and the program
> starts dropping events or otherwise misbehaving.

The important issue was the implementation of process_msgs, which I did
not provide. The design doesn't much care if some events are dropped
because it does not require one signal per object on the queue. It also
avoids race conditions with the manually event reset because there is only
a single consumer thread (which I failed to mention). While I think this
is a fairly solid design, I've begun to understand why simple events were
left out of Boost--it's just too easy to use them improperly. It's times
like these when I wish MS hadn't tried to reinvent the wheel--this entire
dicussion would be moot if there were a builtin implementation of
condvars.

Sean


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