std::async is use to start an asynchronous task for which you don’t need the result right away .It returns a std::future object which will hold the return value of the function. When you need the value, you just call get() on the future and the thread blocks until the future is ready and then returns the value make threads.

std::async takes as argument a callable object, a function for example, and returns a std::future, that will store the result returned by your function or an error message.

#include <future> #include <iostream> using namespace std; int do_some_stuff() { int sum = 0; cout<<"Returning the same sum"<<endl; return sum; } int main() { std::future<int> resultString = std::async(do_some_stuff); cout << " Result is " << resultString.get() << endl; return 0; } ./a.out R eRteusrunlitn gi st he same sum 0

Calling a function Asynchronously with function Argument #include <future> #include <iostream> using namespace std; int cube(unsigned int x){ return x*x*x; } int main() { std::future<int> result = std::async(cube,4); cout << " Cube is running" << endl; //do something when cube is running cout << " Result is " << result.get() << endl; } /a.out Cube is running Result is 64

std::async allows you to pass additional arguments to the function by adding extra arguments to the call, in the same way that std::thread does. If the first argument is a function which expects an argument, then you can specify the argument in the same call of async as second argument as seen in the above example.

By default, it’s up to the implementation whether std::async starts a new thread, or whether the task runs synchronously when the future is waited for. In most cases this is what you want, but you can specify which to use with an additional parameter to std::async before the function to call. This parameter is of the type std::launch, and can either be std::launch::deferred to indicate that the function call is to be deferred until either wait() or get() is called on the future, std::launch::async to indicate that the function must be run on its own thread, or std::launch::deferred | std::launch::async to indicate that the implementation may choose. This last option is the default. If the function call is deferred, it may never actually run.

//async example with deferred #include <future> #include <iostream> using namespace std; string do_some_stuff() { cout<<"Returning the set String"<<endl; return "setString"; } int main() { std::future<string> resultString = std::async(std::launch::deferred,do_some_stuff); cout << resultString.get() << endl; return 0; } /a.out Returning the set String setString //Same Above example if get is not called, async task will run lazily and will not return since get() is not there. #include <future> #include <iostream> using namespace std; string do_some_stuff() { cout<<"Returning the set String"<<endl; return "setString"; } int main() { std::future<string> resultString = std::async(std::launch::deferred,do_some_stuff); cout << "Get is not called" << endl; return 0; } /a.out Get is not called

Some Common Problems with std::async

std::async returns a std::future that holds the return value that will be calculated by the function. when that future gets destroyed it waits until the thread completed, making your code effectively single threaded.This is easily overlooked when you don’t need return value.

#include <future> #include <iostream> using namespace std; string do_some_stuff() { cout<<"Returning the same sum"<<endl; return "setString"; } int main() { std::async(std::launch::async,do_some_stuff); //No return future value making it a single threaded cout << "new element"<< endl; return 0; } ./a.out Returning the same sum new element

std::async works without a launch policy, so std::async(cube,4) in first example compiles. when you do that the system gets to decide if it want to create a thread or not. The idea was that the system choses to make a thread unless it is laready running more threads than it can run efficiently. Unfortunately implementations just choose not to create a thread in that situation,ever .So one should need to override that behavior with launch::async which forces system to create a thread.

References: C++ concurrency in Action, Cplusplusnotesforprofessionals

If you have any feedback, please leave a comment.