70
votes

Can anybody give a high level intuition about when to use each of them?

References:

3
Use whichever one you know how to apply to your problem. Some problems map better to one or the other, and this will naturally be reflected in your thinking. - Ben Voigt
But are they equivalent? I do not think so. Are std::async made only to make life easier or to solve a previous C++ problem? - Javi
Interesting reading (regarding std::async) if using g++: async(f) isn't., and also this - Natan Streppel
@JaviV: They solve the same problem (concurrency) at very different levels of abstraction. - Ben Voigt
@JaviV They are mostly unrelated concerns (deferred asyncs won't even execute on a different thread than the one waiting for it). They are sometimes mostly equivalent conceptually (e.g. start a few tasks and immediately get the corresponding futures or join the corresponding threads). Sometimes they are complementary (e.g. creating lots of deferred asyncs where the associated futures are executed on a thread pool). Sometimes only one of the two concepts is relevant to a problem (e.g. threads only as monitoring or GUI threads; deferred asyncs only to implement lazy evaluation) - Come Raczy

3 Answers

50
votes

It's not really an either-or thing - you can use futures (together with promises) with manually created std::threads. Using std::async is a convenient way to fire off a thread for some asynchronous computation and marshal the result back via a future but std::async is rather limited in the current standard. It will become more useful if the suggested extensions to incorporate some of the ideas from Microsoft's PPL are accepted.

Currently, std::async is probably best suited to handling either very long running computations or long running IO for fairly simple programs. It doesn't guarantee low overhead though (and in fact the way it is specified makes it difficult to implement with a thread pool behind the scenes), so it's not well suited for finer grained workloads. For that you either need to roll your own thread pools using std::thread or use something like Microsoft's PPL or Intel's TBB.

You can also use std::thread for 'traditional' POSIX thread style code written in a more modern and portable way.

Bartosz Milewski discusses some of the limitations of the way std::async is currently specified in his article Async Tasks in C++11: Not Quite There Yet

9
votes

One simple reason I've found is the case when you want a way to detect (via polling) whether an asynchronous job is done. With std::thread, you have to manage it yourself. With std::async you can query std::future::valid() (or use std::future::wait_for/wait_until(...)) to know when it is done.

7
votes

One use-case of using std::futrue over std::thread is you want to call a function which returns a value. When you want return value of the function, you can call get() method of future.

std::thread doesn't provide a direct way to get the return value of the function.