std::async is a way to achieve thread communication. It takes a callable object as an argument. Under the hood, async uses promise-future interface. A promise object is created which executes the callable object and a future object is returned. The returned future can be used to retrieve the result at a later point in time.

std::async can take any callable object as argument. Below code snippet shows usage with a function, function object and a lambda.

#include <iostream>
#include <future>
#include <string>

std::string callableFunc(const std::string& str)
{
    return str + " returned from function.\n";
}

struct CallableFuncObj{
    std::string operator()(const std::string& str) const
    {
        return str + " returned from function struct.\n";
    }
};

int main()
{
    std::string hw = "Hello World ";
    CallableFuncObj funcObj;
    auto funcFut = std::async(callableFunc, hw);
    auto funcStrFut = std::async(funcObj, hw);
    auto lambdaFut = std::async([](const std::string& str){ return str + " returned from lambda.\n";}, hw);

    std::cout << funcFut.get();
    std::cout << funcStrFut.get();
    std::cout << lambdaFut.get();

    return 0;
}

Concurrent or Deferred Execution

The callable object can be executed at the moment the call to async is made or can be deferred to a later point in time by passing an extra argument to the async call.

std::launch::async - It tells the compiler to launch a separate thread to execute the callable object and execute it immediately.

std::launch::deferred - It tells the compiler to perform the execution of callable object in the same thread and delay it to the point when the result is asked for.

Default value for this parameter is std::launch::async std::launch::deferred, which means the compiler can decide which one to pick.

Concurrent Execution:
In the example below, the function gets executed even before the get call to future is made. And it can also been seen that it is executed in separate thread.

Deferred Execution:
In the example below, the function gets executed when the get call to future is made. And it can also been seen that it is executed in same thread.

std::string callableFunc(const std::string& str)
{
    std::cout << "Function thread: " << std::this_thread::get_id() << "\n";
    return str + " returned from function.\n";
}

int main()
{
    std::string hw = "Hello World ";
    std::cout << "Main thread: " << std::this_thread::get_id() << "\n";
    auto funcFut = std::async(std::launch::async, callableFunc, hw);
    //auto funcFut = std::async(std::launch::deferred, callableFunc, hw);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Get value from future\n";
    std::cout << funcFut.get() << "\n";

    return 0;
}

Output for std::launch::async- 
Main thread: 140640628083456
Function thread: 140640620901952
Get value from future
Hello World  returned from function.

Output for std::launch::deferred- 
Main thread: 140249498356480
Get value from future
Function thread: 140249498356480
Hello World  returned from function.

<
Previous Post
Concepts
>
Next Post
Multithreading in C++