4

Consider the following:

#include <boost/thread.hpp>

boost::thread spawn() {
    boost::barrier barrier{2};
    boost::thread ret{[&barrier] {
        // some initialization code  
        barrier.wait();
        // actual thread code
    }};

    barrier.wait();
    return ret;
}

The spawn function creates a boost::barrier object on the stack, spawns a new thread and then waits until it reaches the barrier. The purpose is that spawn function wants to wait until the spawned thread has been actually started and initialized before returning control.

After the new thread reaches the barrier, the spawn function resumes, destroys the barrier object and returns. Looks quite neat.

Is the presented approach safe? If not, what is the recommended way to achieve the desired behaviour? (I guess I could keep the barrier under shared_ptr but that somehow doesn't feel like the right way.)


I see a possible problematic case:

  1. main thread calls wait
  2. spawned thread calls wait and wakes other threads (but the wait function does not finishes its job)
  3. parent thread wakes from wait and destroys the barrier
  4. spawned thread does some other things in wait (eg. looking for completion function) that can crash because they operate on the barrier object that was deleted

So the question likely boils down to whether wait can be treated "atomically" (ie. it won't touch the barrier after threads are waked up) — unless I missed some other risks?

The Boost documentation says:

When the count-th thread calls wait, the barrier is reset and all waiting threads are unblocked.

I'd say that the wording suggests that the barrier is touched first and only after that threads are unblocked — or is it just an unreliable overinterpretation?

Michał W. Urbańczyk
  • 1,453
  • 1
  • 12
  • 20

0 Answers0