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.
#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;
}
Defer: 101
Async: 2
                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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With