Reputation: 63
I'm new to threads in C++ 11. I have two threads and I want to make them start at the exact same time. I could think of two ways of doing it (as below). However, it seems that none of them work as I expected. They are start one thread before launching another. Any hint would be appreciated! Another question is I'm working on a threaded queue. So I would have two consumers and four producers. Is the following code for consumer the right way to go? Is there any reference that anyone can provide?
for(int i = 1; i <= 2; i++)
auto c = async(launch::async, consumer, i);
auto c1 = async(launch::async, consumer, 1);
auto c2 = async(launch::async, consumer, 2);
Upvotes: 2
Views: 2454
Reputation: 795
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.
Upvotes: 3
Reputation: 6775
to launch two threads simultaneously I see no other way than first launching 2 threads the classic way, then blocking them using a barrier to synchronize them, but the release broadcast has no guarantee of re-scheduling them both at the same time. Alternatively you could spin check a global time counter or something but even then...
Upvotes: 1
Reputation: 1467
It is impossible to start two threads at one time. The CPU can only do one thing at a time. It threads by stopping one thread, saving register states, and restoring those of the other thread, and executing that thread for a while. Think of it more like this (though not exactly how it works).
hey cpu, i want to do two things at once, eat apples and bananas
CPU says
ok, well, heres what we will do. Eat a bit of an apple
now, eat some banana
repeat..
Therefore, you can start them in close proximity, but not at the exact same time.
Upvotes: 0