4

I have a scenario for which I am trying to come up with the best synchronization approach. We assume that std::thread in C++11 is present, so no need to worry about differences between various threading libraries etc.

The scenario is this. Thread a, the main thread, wants to hand out tasks to a bunch of worker threads. Then, after giving out its final instruction for the time being, it needs to wait for all the threads to complete their work. We don't want to join them, just wait for them to finish their given task. Then thread a has to analyze the collected data from all threads, and then send out commands to the workers to begin the procedure again.

In short, these are the steps.

  1. Thread a sends command x to all worker threads.
  2. Thread a waits until all the workers have finished.
  3. Thread a does processing.
  4. Go back to 1.

What would you suggest that I use? Simple mutexes? Condition variables? A combination of the two? Any tips on how to structure the synchronization to be as efficient as possible would be appreciated.

Philip Bennefall
  • 1,477
  • 5
  • 20
  • 33

1 Answers1

2

You have n worker threads and one main thread a, which delegates tasks to workers and must wait for them to complete these tasks before assigning them a new batch of tasks.

The basic technique is to use a barrier (like boost::barrier) to synchronize the end of the worker threads and a.

The barrier is inittialized at n+1. Main thread a waits on the barrier, and each worker threads does the same at the end of its task. When the last thread called wait on the barrier, all the threads are woken up, and main thread can continue its work. You may want to add a second barrier to block the worker threads until a new task is assigned to them.

The body of worker thread may look like the following pseudocode:

while (running) {
     startbarrier.wait(); // wait for main thread to signal start
     do_work();
     endbarrier.wait(); // signal end of work
 }

The same thing can also be implemented with semaphores. Both semaphore and barrier can be implemented with a mutex and a condition variable.

See this SO question for more details.

Community
  • 1
  • 1
didierc
  • 14,572
  • 3
  • 32
  • 52