What the other answers said about it not being possible to guarantee that two threads start at the same time is true. Still, if you want to come close there are different ways to do that.
One way is to use a set of std::promises to indicate when everything is ready. Each thread sets a promise to indicate that it's ready and then waits on a (copy of a) std::shared_future obtained from a third std::promise; the main thread waits for all the promises from all the threads to be set and then triggers the threads to go. This ensures that each thread has started and is just before the chunk of code that should be run concurrently.
std::promise<void> go, ready1, ready2; // Promises for ready and go signals
std::shared_future<void> ready(go.get_future()); // Get future for the go signal
std::future<void> done1, done2; // Get futures to indicate that threads have finished
try
{
done1 = std::async(std::launch::async,
[ready, &ready1]
{
ready1.set_value(); // Set this thread's ready signal
ready.wait(); // Wait for ready signal from main thread
consumer(1);
});
done2 = std::async(std::launch::async,
[ready, &ready2]
{
ready2.set_value(); // Set this thread's ready signal
ready.wait(); // Wait for ready signal from main thread
consumer(2);
});
// Wait for threads to ready up
ready1.get_future().wait();
ready2.get_future().wait();
// Signal threads to begin the real work
go.set_value();
// Wait for threads to finish
done1.get();
done2.get();
}
catch (...)
{
go.set_value(); // Avoid chance of dangling thread
throw;
}
Note: most of this answer was copied from "C++ Concurrency in Action" by Anthony Williams (pages 311-312), but I adapted the code to fit the example in the question.