【问题标题】:the behavior of std::async with std::launch::async policystd::async 与 std::launch::async 策略的行为
【发布时间】:2012-04-01 18:28:31
【问题描述】:

我对 std::async 函数与从异步返回的 std::launch::async 策略和 std::future 对象的行为有一些疑问。

在下面的代码中,主线程在async调用创建的线程上等待foo()完成。

#include <thread>
#include <future>
#include <iostream>

void foo()
{
  std::cout << "foo:begin" << std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(10));
  std::cout << "foo:done" << std::endl;
}

int main()
{
  std::cout << "main:begin" << std::endl;
  {
    auto f = std::async(std::launch::async, foo);
    // dtor f::~f blocks until completion of foo()... why??
  }
  std::this_thread::sleep_for(std::chrono::seconds(2));
  std::cout << "main:done" << std::endl;
}

我知道http://www.stdthread.co.uk/doc/headers/future/async.html

与 返回的 std::future 的异步状态应阻塞,直到 未来已准备就绪。

我的问题是:

  • 第一季度。这种行为是否符合当前的 C++ 标准?
  • 第二季度。如果 Q1 的回答是肯定的,哪些陈述是这样说的?

【问题讨论】:

  • 该标准的惊人之处在于,一个脚注通常会完全改变一章......

标签: c++ multithreading c++11


【解决方案1】:

是的,这是 C++ 标准所要求的。 30.6.8 [futures.async] 第 5 段,最后一个项目符号:

— 关联的线程完成与 (1.10) 成功检测到共享状态的就绪状态的第一个函数的返回或与释放共享状态的最后一个函数的返回同步,以先发生者为准。

唯一的std:future 的析构函数满足该条件,因此必须等待线程完成。

【讨论】:

  • OP 的代码在 VS2012 中不一样。它不会阻塞 future 析构函数。是某种错误,还是微软只是接受了 Sutter 的不阻止 dtors 的提议?
  • Microsoft 选择实施 Herb Sutter 的建议,即不阻塞析构函数。
  • 这种行为是一个大问题,但我担心现在修复标准为时已晚。微软之所以选择实施非标准行为,是因为他们不同意,这只会让跨平台开发人员的生活变得困难。
  • 在本周的 C++ 标准委员会会议上,我们正在积极讨论更改标准的提案。上面的代码仍然可以工作(因为它使用了auto),但是std::async 不会再返回std::future --- 而是会返回std::waiting_future。 Herb 表示,微软将根据本周的决定更改他们的代码(即使这是现状)。
猜你喜欢
  • 2012-07-13
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 1970-01-01
  • 2015-08-28
  • 1970-01-01
  • 2019-03-15
相关资源
最近更新 更多