|
Boost Users : |
From: Andreas Huber (ahd6974-spamgroupstrap_at_[hidden])
Date: 2006-02-21 17:21:49
Hi Dave,
David Greene wrote:
> David Greene wrote:
>> If I have an asynchronous state machine running in another thread and
>> I send it an event, is there any way to have the sending thread block
>> until the event is processed?
Yes: Add a boost::function member to the event. Have the member point to
a function which calls notify_one() on a boost::condition. Have the
sending thread call wait() on the condition. When processing the event
inside the state_machine, call the boost::function member.
> I need to use an asynchoronous machine
>> because the rest of my app is threaded but yet there are points where
>> I must synchronize to know the machine is in a certain state before
>> moving on.
>>
>> From the documentation it seems like passing zero to
>> FifoWorker::operator() (via fifo_scheduler::operator()) will do the
>> trick, but I'm not sure.
See below.
> Quick follow-up: when the documentation says that
> FifoWorker::operator() "must only be called from exactly one thread,"
> does that mean it must be called only from one thread at any given
> time (i.e. it must be protected with mutexes or other concurrency
> protection) or that literally only one thread may ever call it and it
> must always be the same thread that calls it?
The latter. fifo_worker::operator() calls terminated(), which in turn
returns the bool member terminated_. This call chain is not protected by
mutexes. Picture the following scenario with one fifo_worker object:
1. Thread A, which is executed on CPU 1, calls operator(). Inside
operator(), terminated_ is modified and operator() returns.
2. Thread B, which is executed on CPU 2, calls operator(), after thread
A has returned from operator().
Nowadays both CPUs tend to have caches. Whether or not the cache
contents is guaranteed to be written back to the main memory when thread
A returns depends on the architecture of your hardware. IIRC, on X86
architectures there is such a guarantee. On other architectures you
might need to use mutexes or a similar concept to guarantee that thread
B sees the updates of thread A.
> If it's the latter then that changes things quite dramatically and I
> probably want a blocking scheduler and will need to create another
> thread just to wait on empty and call operator() when full.
I'm not sure I understand that. You only need to create a blocking
scheduler and call operator() on it, that's it. operator() will return
when you call terminate() from any other thread.
HTH & Regards,
-- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.
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