Task executed with std::async is blocking like if

2020-04-23 03:18发布

I am having a hard time understanding why following code blocks:

  {
    std::async(std::launch::async, [] { std::this_thread::sleep_for(5s); 
    // this line will not execute until above task finishes?
  }

I suspect that std::async returns std::future as temporary which in destructor joins on the task thread. Is it possible?

Full code is below:

int main() {
  using namespace std::literals;

  {
    auto fut1 = std::async(std::launch::async, [] { std::this_thread::sleep_for(5s); std::cout << "work done 1!\n"; });
    // here fut1 in its destructor will force a join on a thread associated with above task.
  }
  std::cout << "Work done - implicit join on fut1 associated thread just ended\n\n";

    std::cout << "Test 2 start" << std::endl;
  {
    std::async(std::launch::async, [] { std::this_thread::sleep_for(5s); std::cout << "work done 2!" << std::endl; });
    // no future so it should not join - but - it does join somehow.
  }
  std::cout << "This shold show before work done 2!?" << std::endl;

}

标签: c++ c++11
1条回答
一夜七次
2楼-- · 2020-04-23 03:22

Yes, std::future returned by async has the special property of waiting for the task to be completed in the destructor.

This is because loose threads are bad news, and the only token you have to wait for that thread is in the destructor of the future.

To fix this, store the resulting futures until either you need the result to be done, or in extreme cases the end of the program.

Writing your own thread pool system is also a good idea; I find C++ threading primitives to be sufficient to write a threading system, but use in the raw is not something I'd encourage outside of tiny programs.

查看更多
登录 后发表回答