Near the beginning of this clip from C++ And Beyond, I heard something about problems with std::async
. I have two questions:
For a junior developer, is there a set of rules for what to do and what to avoid when using std::async
?
What are the problems presented in this video? Are they related to this article?
The function template async runs the function f asynchronously (potentially in a separate thread which might be a part of a thread pool) and returns a std::future that will eventually hold the result of that function call. 1) Behaves as if (2) is called with policy being std::launch::async | std::launch::deferred.
As the name indicates, C++ async is a function template fn, which takes functions or function objects as arguments (basically called callbacks) and runs them asynchronously. It returns the std:: the future object which is used to keep the result of the above function. The result is stored in the shared state.
Example# std::async is also able to make threads. Compared to std::thread it is considered less powerful but easier to use when you just want to run a function asynchronously.
One nice thing about std::async is that it manages a thread pool under the hood. So there is no worry that every time we invoke std::async a new thread is launched.
There are several issues:
std::async
without a launch policy lets the runtime library choose whether to start a new thread or run the task in the thread that called get()
or wait()
on the future. As Herb says, this is the case you most likely want to use. The problem is that this leaves it open to the QoI of the runtime library to get the number of threads right, and you don't know whether the task will have a thread to itself, so using thread-local variables can be problematic. This is what Scott is concerned about, as I understand it.
Using a policy of std::launch::deferred
doesn't actually run the task until you explicitly call get()
or wait()
. This is almost never what you want, so don't do that.
Using a policy of std::launch::async
starts a new thread. If you don't keep track of how many threads you've got, this can lead to too many threads running.
Herb is concerned about the behaviour of the std::future
destructor, which is supposed to wait for the task to complete, though MSVC2012 has a bug in that it doesn't wait.
For a junior developer, I would suggest:
std::async
with the default launch policy.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With