Reputation: 11
I have a main program that needs to launch a number of threads that immediately wait on a condition_variable. The main program then enters a loop. Each iteration of the loop by the main program does a notify_all to awaken all the threads. The main program then waits for all the threads to complete their processing before beginning the next iteration of the main loop.
I know how to do this for one thread. I think I know how to do this with multiple threads, but I have a question with how the main program should go about waiting on all the threads. The main program cannot do it with join because the threads are going to wait for the next iteration of the main loop rather than terminate. So the main program has to do it with wait.
Each thread will of course notify the main program that it is complete for this iteration immediately before it goes back into wait. I know how to do notify and wait back and forth between the main program and one thread, and I know generally how to use condition_variables. I know how to avoid lost wakeups and spurious wakeup events, etc. But I'm a little fuzzy on how the main program is supposed to wait to be notified by all the threads before proceeding with the next iteration of the loop. Conceptually, the main program needs to wait on multiple condition_variables, one for each thread. But that's not how condition_variables work. You can only wait on one condition_variable at a time.
I can think of two ways to handle the main program waiting on all the threads. The two ways I can think of to do it is that the main program would be waiting on a single condition variable that all the threads would notify when they were done or that there would be multiple condition variables that the main program would be waiting on, one per thread, and the main program would wait for them one at a time. I'm sure I know how to make the latter case work. The question is whether it's possible to make the former case work. If it could work, I would picture a different Boolean variable that would be set by each thread when it finished an iteration. The main program's wait would have a predicate that tested each Boolean variable in turn. The wait processing would loop until it had found all the boolean variables turned on. So that's the question. Can I get by with one condition_variable that each thread notifies? Or do I need a separate condition_variable for each thread to notify?
It doesn't matter to my question, but during iteration N of the loop, the work being done by each thread is completely independent of the work being done at that time by the other threads. But during iteration N+1 of the loop, the work being done be each thread depends on the work that was done by all the threads during iteration N. That's why the main program has to wait on all the threads to complete an iteration before it can notify any of the threads to begin the next iteration. Were it not for that requirement, I wouldn't even need condition_variables. The threads could run asynchronously. The main program could just launch them all and wait for them all to complete via a join.
Upvotes: 0
Views: 93
Reputation: 182883
Can I get by with one condition_variable that each thread notifies? Or do I need a separate condition_variable for each thread to notify?
Either method works without any issues. Waiting for all of some set of things to happen can be accomplished simply by waiting for each of the things to happen successively in any order. You can use a shared condition variable or a different condition variable for each event.
Upvotes: 0
Reputation: 22094
You can use a counter, which needs to be protected by mutex. Seit it to 0
before you start, and each thread increases it when it is done, so you need only a single object to check against which can be easily done with a condition variable.
if (DoneCount == ThreadCount)
// All threads done.
Upvotes: 1