Hi! I have a quite simple problem, but I still lack a nice implementation in C++ with boost. My problem is, that I have two threads A and B and thread A needs some information that B will calculate at runtime. Therefore I need some kind of synchronization. So my first attempt was to use a mutex and a condition variable: Thread A: boost::thread::mutex::scoped_lock lock ( mMutex ); mConditionVar.wait ( lock ); Thread B: mConditionVar.notify_one (); This works nice as long as thread A already started waiting on the condition before thread B finished providing it. Otherwise the notify will be lost. So my second attempt was to use a barrier: Init barrier with count 2 Thread A: mBarrier.wait (); Thread B: mBarrier.wait (); This works fine and A will wait until the result is available and it doens't matter if it starts waiting before or after B finished calculaating. But the problem now is that B also needs to wait for A to reach the point in execution. So if I just want to signal thread A from thread B that some point was reached. I don't know how to do it with boost. If I would have a semaphore available I could init it with 0 and thread A tries to decrement it while thread B will increment it once it reached the point. But http://www.boost.org/doc/html/thread/faq.html#id1747096 says: "Semaphore was removed as too error prone. The same effect can be achieved with greater safety by the combination of a mutex and a condition variable." So how exactly is this achieved with the mutex and condition variable? I always only come up with a mutex, condition variable and a bool which all three must be shared between both threads. I would greatly appreciate any suggestions! Thanks, Fabian
On Wed, 21 Nov 2007 23:25:36 +0100, Fabian Sturm wrote:
This works fine and A will wait until the result is available and it doens't matter if it starts waiting before or after B finished calculaating. But the problem now is that B also needs to wait for A to reach the point in execution.
Why not do this: void threadB() { g_value = do_my_expensive_calc(); barrier2.wait(); // start waiting *after* calculation is done } void threadA() { barrier2.wait(); // now can read value do_something_with_value(g_value) } Then thread B can calculate without waiting for thread A but neither thread will exit until they both reach the barrier. -- Sohail Somani http://uint32t.blogspot.com
Hi! Am Mittwoch, den 21.11.2007, 22:39 +0000 schrieb Sohail Somani:
Why not do this:
void threadB() { g_value = do_my_expensive_calc(); barrier2.wait(); // start waiting *after* calculation is done }
void threadA() { barrier2.wait(); // now can read value do_something_with_value(g_value) }
Then thread B can calculate without waiting for thread A but neither thread will exit until they both reach the barrier.
A well I guess I wasn't expressing good enough. I look for a nice solution where thread B is completely independent of A. But A waits for B doing some work. e.g. void threadB () { do_something (); g_value = do_my_expensive_calc (); inform_thread_A (); do_something_else (); } So a barrier won't work, since it synchronizes both threads. Thanks, Fabian
On Thu, 22 Nov 2007 01:56:59 +0100, Fabian Sturm wrote:
A well I guess I wasn't expressing good enough. I look for a nice solution where thread B is completely independent of A. But A waits for B doing some work.
I don't think there is a nice solution but I'm pretty sure you would need two way communication and I don't envy you having to debug and test that. -- Sohail Somani http://uint32t.blogspot.com
On Thu, Nov 22, 2007 at 01:56:59AM +0100, Fabian Sturm wrote:
A well I guess I wasn't expressing good enough. I look for a nice solution where thread B is completely independent of A. But A waits for B doing some work.
Use a message queue..
inform_thread_A ();
This would send a message to A through the message queue, and A would check at convenient times whether a message has arrived. Optionally, you can send a signal (on POSIX) to thread A to make it immediately notice that there's a message. POSIX message queues can be configured to do that for you automatically.
Fabian Sturm
Hi!
I have a quite simple problem, but I still lack a nice implementation in C++ with boost.
My problem is, that I have two threads A and B and thread A needs some information that B will calculate at runtime. Therefore I need some kind of synchronization.
So my first attempt was to use a mutex and a condition variable:
Thread A:
boost::thread::mutex::scoped_lock lock ( mMutex ); mConditionVar.wait ( lock );
Thread B:
mConditionVar.notify_one ();
Correct way to use condvar is the following: Thread A: mutex::scoped_lock lock(mutex); while (!dataCalculated) condvar.wait(lock); Thread B: mutex::scoped_lock lock(mutex); dataCalculated = true; condvar.notify_one(); Instead of 'while' loop you can use condition::wait with a predicate: Thread A: mutex::scoped_lock lock(mutex); condvar.wait(lock, var(dataCalculated)); Regards, Roman Perepelitsa.
On Nov 21, 2007, at 5:25 PM, Fabian Sturm wrote:
My problem is, that I have two threads A and B and thread A needs some information that B will calculate at runtime. Therefore I need some kind of synchronization.
So my first attempt was to use a mutex and a condition variable:
Thread A:
boost::thread::mutex::scoped_lock lock ( mMutex ); mConditionVar.wait ( lock );
Thread B:
mConditionVar.notify_one ();
This works nice as long as thread A already started waiting on the condition before thread B finished providing it. Otherwise the notify will be lost.
You need to create a shared condition variable, set by thread B and
read by thread A.
Thread A has to wait on the condition variable in a loop, like this:
shared variable:
bool theCondition = false;
Thread A:
{
boost::thread::mutex::scoped_lock lock ( mMutex );
while (!theCondition) {
mConditionVar.wait ( lock );
}
}
Thread B:
{
boost::thread::mutex::scoped_lock lock ( mMutex );
theCondition = true;
mConditionVar.notify_one ();
}
I suggest you take a look at a tutorial text on POSIX threads
(pthreads); it should explain the use of mutexes and condition
variables more thoroughly.
Regards,
-Steve
--
Steve Byan
Hi! Thanks for the replies! I didn't expect so many! So it seems that the preferred way to do it is using three shared variables. The mutex the condition and a bool, which was the same I was thinking about. Therefore my question for a solution with less shared resoures. Since the FAQ states there is a solution with only a mutex and a condition variable. Anyways its good to know that the given examples are common practice. Thanks again. Fabian Am Donnerstag, den 22.11.2007, 08:48 -0500 schrieb Steve Byan:
On Nov 21, 2007, at 5:25 PM, Fabian Sturm wrote:
My problem is, that I have two threads A and B and thread A needs some information that B will calculate at runtime. Therefore I need some kind of synchronization.
So my first attempt was to use a mutex and a condition variable:
Thread A:
boost::thread::mutex::scoped_lock lock ( mMutex ); mConditionVar.wait ( lock );
Thread B:
mConditionVar.notify_one ();
This works nice as long as thread A already started waiting on the condition before thread B finished providing it. Otherwise the notify will be lost.
You need to create a shared condition variable, set by thread B and read by thread A. Thread A has to wait on the condition variable in a loop, like this:
shared variable: bool theCondition = false;
Thread A:
{ boost::thread::mutex::scoped_lock lock ( mMutex ); while (!theCondition) { mConditionVar.wait ( lock ); } }
Thread B:
{ boost::thread::mutex::scoped_lock lock ( mMutex ); theCondition = true; mConditionVar.notify_one (); }
I suggest you take a look at a tutorial text on POSIX threads (pthreads); it should explain the use of mutexes and condition variables more thoroughly.
Regards, -Steve
Fabian Sturm wrote:
I have a quite simple problem, but I still lack a nice implementation in C++ with boost.
My problem is, that I have two threads A and B and thread A needs some information that B will calculate at runtime. Therefore I need some kind of synchronization.
You might find this example helpful: http://www.boostcookbook.com/Recipe:/1234841 Note the condition and mutex, but there is also a bool used for signalling the completion status. So the condition is only used to signal a /change/ in status, but the status itself is the bool. K -- http://www.kirit.com/
participants (6)
-
Fabian Sturm
-
Kirit Sælensminde
-
Roman Perepelitsa
-
Sohail Somani
-
Steve Byan
-
Zeljko Vrba