Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should I use std::async?

I'm trying to explore all the options of the new C++11 standard in depth, while using std::async and reading its definition, I noticed 2 things, at least under linux with gcc 4.8.1 :

  • it's called async, but it got a really "sequential behaviour", basically in the row where you call the future associated with your async function foo, the program blocks until the execution of foo it's completed.
  • it depends on the exact same external library as others, and better, non-blocking solutions, which means pthread, if you want to use std::async you need pthread.

at this point it's natural for me asking why choosing std::async over even a simple set of functors ? It's a solution that doesn't even scale at all, the more future you call, the less responsive your program will be.

Am I missing something ? Can you show an example that is granted to be executed in an async, non blocking, way ?

like image 797
user2485710 Avatar asked Jul 31 '13 06:07

user2485710


People also ask

What does STD async do?

std::async. Calls fn (with args as arguments) at some point, returning without waiting for the execution of fn to complete. The value returned by fn can be accessed through the future object returned (by calling its member future::get ).

What is STD async C++?

C++ Futures and Promises std::future and std::async This is to avoid a new thread being created in every call. In the case of our example, the calls to std::async are made out of order, the they synchronize at the calls for std::future::get() . std::launch_async forces a new thread to be created in every call.

Does STD async create new thread?

If the deferred flag is set, a callable function will be stored together with its arguments, but the std::async function will not launch a new thread.

Does STD async use thread pool?

For example, on MSVC std::async is always async, unless std::launch::deferred is specified, and when it is async, it is always in a thread pool.


1 Answers

  • it's called async, but it got a really "sequential behaviour",

No, if you use the std::launch::async policy then it runs asynchronously in a new thread. If you don't specify a policy it might run in a new thread.

basically in the row where you call the future associated with your async function foo, the program blocks until the execution of foo it's completed.

It only blocks if foo hasn't completed, but if it was run asynchronously (e.g. because you use the std::launch::async policy) it might have completed before you need it.

  • it depends on the exact same external library as others, and better, non-blocking solutions, which means pthread, if you want to use std::async you need pthread.

Wrong, it doesn't have to be implemented using Pthreads (and on Windows it isn't, it uses the ConcRT features.)

at this point it's natural for me asking why choosing std::async over even a simple set of functors ?

Because it guarantees thread-safety and propagates exceptions across threads. Can you do that with a simple set of functors?

It's a solution that doesn't even scale at all, the more future you call, the less responsive your program will be.

Not necessarily. If you don't specify the launch policy then a smart implementation can decide whether to start a new thread, or return a deferred function, or return something that decides later, when more resources may be available.

Now, it's true that with GCC's implementation, if you don't provide a launch policy then with current releases it will never run in a new thread (there's a bugzilla report for that) but that's a property of that implementation, not of std::async in general. You should not confuse the specification in the standard with a particular implementation. Reading the implementation of one standard library is a poor way to learn about C++11.

Can you show an example that is granted to be executed in an async, non blocking, way ?

This shouldn't block:

auto fut = std::async(std::launch::async, doSomethingThatTakesTenSeconds); auto result1 = doSomethingThatTakesTwentySeconds(); auto result2 = fut.get(); 

By specifying the launch policy you force asynchronous execution, and if you do other work while it's executing then the result will be ready when you need it.

like image 159
Jonathan Wakely Avatar answered Sep 22 '22 10:09

Jonathan Wakely