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