Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ async + future (deferred vs async)

This is the test program that I am working with. Can someone please describe in detail what is happening and the reason for this output?

Why does launch::async get the value of g_num as 0, while launch::deferred gets 100?

Both launch::async and launch::deferred got correct values of arg that is on the main stack, which I believe means they should have both gotten 100.

The code:

#include <iostream>
#include <future>
using namespace std;
    
thread_local int g_num;
    
int read_it(int x) {
    return g_num + x;
}

int main()
{
    g_num = 100;

    int arg = 1;
    future<int> fut = async(launch::deferred, read_it, arg);
    arg = 2;
    future<int> fut2 = async(launch::async, read_it, arg);

    cout << "Defer: " << fut.get() << endl;
    cout << "Async: " << fut2.get() << endl;

    return 0;
}

The output:

Defer: 101
Async: 2
like image 756
Seoul Avatar asked Feb 22 '18 02:02

Seoul


People also ask

Does STD async create a new thread?

If the deferred flag is set (i.e. (policy & std::launch::deferred) ! = 0), then async converts f and args... the same way as by std::thread constructor, but does not spawn a new thread of execution.

Does STD async use a thread pool?

std::async(std::launch::async, ...) launches a new thread for every invocation. On Mac and Linux, no thread pool is used so you have to pay the price of thread creation (about 0.5ms on my laptop) for each call.

Does C++ have async?

As the name indicates, C++ async is a function template fn, which takes functions or function objects as arguments (basically called callbacks) and runs them asynchronously. It returns the std:: the future object which is used to keep the result of the above function. The result is stored in the shared state.

Does C++ have async await?

Async and await in C++ helps in writing asynchronous code simply. Calculation and getting data from I/O is an example for Async/await operations.


2 Answers

The documentation states that launch::deferred will invoke the function on the calling thread, while launch::async will invoke the function on a new thread.

For the calling thread, the value of g_num is whatever you set it to in main. For a new thread, the value is value-initialized (0 for int) since you never set it. Thanks @MilesBudnek for the correction.

like image 103
merlin2011 Avatar answered Sep 28 '22 15:09

merlin2011


g_num is define as thread_local this means every thread in your app has its own copy of g_num

launch::deferred runs on the calling thread. g_num on the main thread was changed to 100. It was not changed on the thread that was launched with launch::async which is the reason its value was still the default one.

like image 40
Eyal Cinamon Avatar answered Sep 28 '22 14:09

Eyal Cinamon