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.

+3


source to share


2 answers


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.

+4


source


From this std::async

help topic

If the std::future

derived from std::async

does not move out of reference or bind to a reference, the destructor std::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"

.

+2


source







All Articles