[Threads] uncoditional scoped lock?

Hi, Somewhat longer-than-normal-noise follows :) Consider the following pseudo-code which has a race condition: condition g_some_cond; mutex g_condition_mtx; void thread_fn() { { ... // get lock g_some_cond.wait(condition_lock); } // do work } void main_thread() { thread_group grp; // Start all threads and have them wait on the condition for(i in [0,N)) grp.create_thread(&thread_fn); { ... // get lock g_some_cond.notify_all(); // let threads continue } } The race condition is of course that it is possible that not all threads actually start waiting on the condition before notify_all() is called. In this case, it is possible to solve the race condition in two ways: 1) Have the last thread that reaches the condition wait, signal to the main thread 2) Have the main thread checking the condition before notify_all() I don't really like the first case because it requires bi-directional signalling between the threads. Though in my ignorance, I really do consider it the correct solution. The second solution would look something like this: while(true) { scoped_lock cond_lock(g_condition_mtx); // .num_waiting_threads() is made up if(N_EXPECTED_THREADS==g_some_cond.num_waiting_threads()){break;} // release lock } Should the second pattern be encapsulated in the condition object somehow? It is almost like timed_wait(mtx,xt,pred) but there is no timeout. So maybe untimed_wait()? Is there another way to do this? Thanks for your eyes! Sohail

I would think the best way to synchronize this type of operation, where you want all the threads to "wait until it we are all ready" is via boost::barrier.
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Sohail Somani Sent: Friday, January 12, 2007 12:39 PM To: boost@lists.boost.org Subject: [boost] [Threads] uncoditional scoped lock?
Hi,
Somewhat longer-than-normal-noise follows :)
Consider the following pseudo-code which has a race condition:
condition g_some_cond; mutex g_condition_mtx;
void thread_fn() { { ... // get lock g_some_cond.wait(condition_lock); } // do work }
void main_thread() { thread_group grp; // Start all threads and have them wait on the condition for(i in [0,N)) grp.create_thread(&thread_fn);
{ ... // get lock g_some_cond.notify_all(); // let threads continue } }
The race condition is of course that it is possible that not all threads actually start waiting on the condition before notify_all() is called. In this case, it is possible to solve the race condition in two ways:
1) Have the last thread that reaches the condition wait, signal to the main thread 2) Have the main thread checking the condition before notify_all()
I don't really like the first case because it requires bi-directional signalling between the threads. Though in my ignorance, I really do consider it the correct solution. The second solution would look something like this:
while(true) { scoped_lock cond_lock(g_condition_mtx); // .num_waiting_threads() is made up if(N_EXPECTED_THREADS==g_some_cond.num_waiting_threads()){break;} // release lock }
Should the second pattern be encapsulated in the condition object somehow? It is almost like timed_wait(mtx,xt,pred) but there is no timeout. So maybe untimed_wait()? Is there another way to do this?
Thanks for your eyes!
Sohail _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

By the way, what about extending barrier so that it can use any functor not only waiting_threads == m_threshold? At least timed_barrier, which unblocks when (waiting_threads == m_threshold || time_since_first_wait > m_time_threshold), and maybe unblocks in destructor. So it'll implement scenario: do the work in groups, i.e. not very often. That can be for example some time-expensive background cached work.

Sohail Somani wrote:
Somewhat longer-than-normal-noise follows :)
Consider the following pseudo-code which has a race condition:
<code snipped> Could you please tell me what is the purpose of the code, i.e. what are you trying to achieve? What is different between just starting all threads and letting them do their work, and starting them holding them and then starting again? Are you trying to emulate something similar as starting the threads in a suspended state, later trying to fire them at once? Roland

From: boost-bounces@lists.boost.org on behalf of Roland Schwarz Are you trying to emulate something similar as starting the threads in a suspended state, later trying to fire them at once? --------------------------------- Yep, thats it.

Sohail Somani wrote:
From: boost-bounces@lists.boost.org on behalf of Roland Schwarz
Are you trying to emulate something similar as starting the threads in a suspended state, later trying to fire them at once? --------------------------------- Yep, thats it.
What is the reason for trying this? I mean, you still will not be able to start them 'at once'. What I want to say is: you might see almost the same behaviour as when 'just starting them'. If your application explicitely depends on starting the threads at the same time you should consider rethinking your design. Roland

Are you trying to emulate something similar as starting the threads in a suspended state, later trying to fire them at once? --------------------------------- Yep, thats it.
What is the reason for trying this? I mean, you still will not be able to start them 'at once'. What I want to say is: you might see almost the same behaviour as when 'just starting them'. If your application explicitely depends on starting the threads at the same time you should consider rethinking your design. ---------------- The code was only testing for that condition where a lot of threads might be in the same section at once. I noticed that if I just let them start working as I created them, the first one usually got to do the work first and there were never too many threads in the section at the same time. I was really testing, or trying to test, that doing the work was thread-safe. Not sure if there is a better way to test if something is thread-safe without lots of threads in it at the same time!
participants (4)
-
Dmitry Ivankov
-
Jerry Lawson
-
Roland Schwarz
-
Sohail Somani