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:
- main thread calls
wait
- spawned thread calls
wait
and wakes other threads (but thewait
function does not finishes its job) - parent thread wakes from
wait
and destroys the barrier - 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?