Click here to Skip to main content
11,484,402 members (65,936 online)
Click here to Skip to main content

Simple Introduction to std::future and std::async

, 14 Oct 2014 CPOL 9.5K 19
Rate this:
Please Sign up or sign in to vote.
Simple introduction to std::future and std::async and why they can be useful.

Introduction

Let us consider a simple thing: use some worker thread to compute a value. In the source code, it can look like that:

std::thread t([]() { auto res = perform_long_computation(); });

We would like to obtain the result when it is completed of course. But how to do it efficiently?

A shared variable can be used:

MyResult sharedRes;
std::thread t([&]() { sharedRes = perform_long_computation(); });

But that way, we need to know that the thread t is finished and sharedRes contain computed value; A lot of constructions can be used here: atomics, mutexes, condition variables, etc. but maybe there is a better and simpler way of doing that? 

Let us have a look at this code:

auto result = std::async([]() { return perform_long_computation(); });
MyResult finalResult = result.get();

Isn't that simpler? But what actually happened there?

The Future

In C++11 in the Standard Library, we have all sorts of concurrency features. As usual, we have threads, mutexes, atomics, etc. Fortunately for us, the library went further and added some higher level structures. In our example, we need to look at future and async.

If we do not want to get into much details, all we need to know is that std::future<T> holds a shared state and std::async allow us to run the code asynchronously. In our case, we can rewrite it to:

std::future<MyResult> result = std::async([]() { return perform_long_computation(); });
MyResult finalResult = result.get();

Thus result is not a direct value computed in the thread but it is some form of a guard that makes sure the value is ready when we call .get() method. All the magic (synchronization) happens underneath. Often it will simply block the calling thread and wait for the data (or exception). 

This opens some interesting possibilities and we can start with Task Based Parallelism. We can now build some form of a pipeline where data flows from one side to the other, but in the middle computation can be distributed among several threads. Such constructions definitely deserve more investigation!

Below, there is a simple idea of the mentioned approach: you divide your computation into several separate parts, call them asynchronously and at the end collect the final result. It is up to the system/library to decide if each part is called on a dedicated thread (if available), or just run it on only one thread. This makes the solution more scalable.

Task Based Parallelism idea

Notes

  • .get() can be called only once! The second time we will get exception. If you want to fetch the result from several threads or several times in single thread, you can use std::shared_future.
  • std::async can run code in the same thread as the caller. Launch Policy can be used to force truly asynchronous call - std::launch::async or std::launch::deferred
  • when there is an exception in the future (inside our lambda or function), this exception will be propagated and rethrown in the .get() method.

References

  • See The C++ Standard Library: A Tutorial and Reference (2nd Edition), chapter 18.1 for a great introduction to the concurrency in std.
  • See The C++ Programming Language, 4th Edition , chapter 41
  • C++ Concurrency in Action: Practical Multithreading

History

  • 14th October 2014 - added an image with Task Based Parallelism idea
  • 20th January 2014 - minor changes 
  • 17th January 2014 - Initial version 

Tip based on the original post at my site.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Bartlomiej Filipek
Software Developer
Poland Poland
Software developer interested in creating great code and passionate about teaching.

Technologies I use(d): C++, C#, JavaScript, OpenGL, GLSL, DirectX, OpenCL, CUDA, Windows Api, MFC, Visual Studio and even HTML and CSS.

See my programming blog: www.bfilipek.com
Follow on   Twitter   Google+

Comments and Discussions

 
Questionshared_res Pin
geoyar15-Oct-14 11:50
membergeoyar15-Oct-14 11:50 
AnswerRe: shared_res Pin
Bartlomiej Filipek15-Oct-14 21:48
memberBartlomiej Filipek15-Oct-14 21:48 
GeneralMy vote of 5 Pin
Mihai MOGA18-Apr-14 22:32
professionalMihai MOGA18-Apr-14 22:32 
GeneralRe: My vote of 5 Pin
Bartlomiej Filipek19-Apr-14 0:06
memberBartlomiej Filipek19-Apr-14 0:06 
QuestionA doubt Pin
David Serrano Martínez19-Jan-14 8:37
memberDavid Serrano Martínez19-Jan-14 8:37 
AnswerRe: A doubt Pin
Bartlomiej Filipek19-Jan-14 20:42
memberBartlomiej Filipek19-Jan-14 20:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150520.1 | Last Updated 14 Oct 2014
Article Copyright 2014 by Bartlomiej Filipek
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid