Std :: async does not work asynchronously
I have the following very simple code:
void TestSleep()
{
std::cout << "TestSleep " << std::endl;
sleep(10);
std::cout << "TestSleep Ok" << std::endl;
}
void TestAsync()
{
std::cout << "TestAsync" << std::endl;
std::async(std::launch::async, TestSleep);
std::cout << "TestAsync ok!!!" << std::endl;
}
int main()
{
TestAsync();
return 0;
}
Since I am using std::launch::async
, I expect TestSleep()
to run asynchronously and I will have the following output:
TestAsync
TestAsync ok!!!
TestSleep
TestSleep Ok
But I actually have an output to run synchronously:
TestAsync
TestSleep
TestSleep Ok
TestAsync ok!!!
Could you please explain why and how to make the TestSleep
call really asynchronous.
source to share
std::async()
returns an instance std::future
. If you look at the std::future
destructor documentation it says the following:
these actions will not block for the shared state to be ready, except that it can block if all of the following are true: the shared state was created by a call to std :: async, the shared state is not ready yet and this was the last link on the general condition.
You are not storing the return value std::async()
in a local variable, but that value is still created and must be destroyed. Since the destructor will block until the function returns, this will make it synchronous.
If you change TestAsync()
to return the std::future()
created std::async()
one then it must be asynchronous.
source to share
From this std::async
help topic
If the
std::future
derived fromstd::async
does not move out of reference or bind to a reference, the destructorstd::future
will block at the end of the complete expression until the asynchronous operation completes, essentially generating code. synchronous
Here's what's going on here. Since you are not storing the future that returns std::async
, it will be destroyed at the end of the expression (which is the call std::async
) and will block until the thread finishes.
If you, for example,
auto f = std::async(...);
then destruction f
at the end TestAsync
will block, and the text "TestAsync ok!!!"
must be printed before "TestSleep Ok"
.
source to share