Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::async doesn't 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 use std::launch::async I expect that TestSleep() will be run asynchronously and I will have the following output:

TestAsync
TestAsync ok!!!
TestSleep 
TestSleep Ok

But really I have the output for synchronous run:

TestAsync
TestSleep 
TestSleep Ok
TestAsync ok!!!

Could you explain why and how to make TestSleep call really asynchronously.

like image 509
Roman Kazmin Avatar asked Jun 20 '17 13:06

Roman Kazmin


2 Answers

From this std::async reference notes section

If the std::future obtained from std::async is not moved from or bound to a reference, the destructor of the std::future will block at the end of the full expression until the asynchronous operation completes, essentially making code ... synchronous

This is what happens here. Since you don't store the future that std::async returns, it will be destructed at the end of the expression (which is the std::async call) and that will block until the thread finishes.

If you do e.g.

auto f = std::async(...);

then the destruction of f at the end of TestAsync will block, and the text "TestAsync ok!!!" should be printed before "TestSleep Ok".

like image 156
Some programmer dude Avatar answered Oct 31 '22 15:10

Some programmer dude


std::async() returns an instance of std::future. If you look at the documentation for std::future's destructor, it says the following:

these actions will not block for the shared state to become ready, except that it may block if all of the following are true: the shared state was created by a call to std::async, the shared state is not yet ready, and this was the last reference to the shared state.

You aren't storing the return value of std::async() into a local variable, but that value is still created and must be destroyed. Since the destructor will block until your function returns, this makes it synchronous.

If you change TestAsync() to return the std::future() created by std::async(), then it should be asynchronous.

like image 43
Andy Avatar answered Oct 31 '22 16:10

Andy