I don't get the reason behind using std::async with std::lauch::async flag, instead of simply calling the function passed to std::async. Are there any specials guarantees?
2 Answers
According to the documentation, there is an overload that just takes the function and its arguments. You're using an overload that accepts a more specific policy.
async(f, args...) is equivalent to async(std::launch::async | std::launch::deferred, f, args...), where the presence of both flags leaves it up to the implementation as to whether the function is simply de-coupled from the current call stack (deferred to execution of the first non-timed wait function; this is called lazy evaluation), or actually multi-threaded.
The call you're using, by giving only std::launch::async, ensures that the function is definitely executed in its own thread, avoiding any work blocking the calling thread.
Both variants are still, of course, wholly dissimilar from simply invoking f(args...) directly, which guarantees immediate evaluation.
8 Comments
std::launch::async | std::launch::deferred is that it gives the implementation not only the choice between async and deferred execution, but it also allows the implementation to defer making that choice. That is, the implementation might not choose either policy immediately, but sometime later might choose to do asynchronous execution (e.g., after another thread completes and a core becomes available). As far as I know Microsoft's implementation is the only one that takes advantage of this, and I believe they were responsible for putting this latitude into the spec.std::launch::async?" No, the scheduler would have to completely starve some threads for that to happen, which goes against 1.10/2. "And how does your program portably detect that that happened," The program operator detects it when a program that should complete fails to make progress. "how did deferring the decision [...] make a difference?" The implementation included implicit dependencies for the decision, resulting in circular dependencies that don't appear in the source and which prevent the program from completing.Yes the calling thread does not block because std::async generates a separate thread to invoke the function. That means if you click on a GUI Button to start the processing of a complex task which will take several minutes then the GUI responses although the processing is not finished yet.
std::lauch::deferred? Becausestd::lauch::asyncbehaves completely different from just calling the function, excuting it asynchronously in another thread (but maybe you're actually asking for the reasons to do so in the first place, which would be a much more fundamental question, though).std::asyncand if it's that special case you're after, you might want to clarify your question a bit.