std :: list <std :: future>析构函数不会阻塞

我有一个多线程应用程序,有一个循环等待用户输入作为主线程。 在正确的输入上,它应该停止循环并等待所有其他线程,以便正常结束。

为此,我创建了一个std :: list,其中放置了为创建线程而创建的std :: future对象

std::list<std::future<int>> threads;
threads.emplace_front(std::async(std::launch::async, ...));

我觉得,让列表超出范围,应该阻塞,直到所有线程都返回它们的主函数,因为列表析构函数将破坏所有std :: future元素,并且这些元素的析构函数将等待,线程将完。

编辑:因为它是相关的,我会在这里添加它:这是在Win7与MSVC版本在Visual Studio 2013专业版/编辑

当我尝试这个时,它没有阻塞,我不得不补充

for (auto it = threads.begin(); it != threads.end(); ++it) {
    it->get();
}

到该函数的结尾,以正确阻止。

我是否错误地理解了某些内容,或者是否需要以不同的方式创建线程,才能在此执行我想要做的事情?


这是一个已修复的MSVC错误,但直到MS发布新版本的Visual C ++(可能在2015年有一段时间)之前,该修复程序将不可用。(它也适用于CTP中的新版本,但它很漂亮不好的想法,用于任何生产代码...)

正如Scott Meyers在他的博客文章中解释的, std::future使用launch::async策略返回的std::async调用的析构函数需要阻塞,直到生成的线程完成执行(§30.6.8[futures。异步] / P5):

如果实现选择launch::async策略,

  • [...]
  • 相关联的线程完成与(1.10)成功检测到共享状态的就绪状态的第一个函数的返回或与释放共享状态的最后一个函数的返回(以先发生者为准)进行同步。
  • 在这种情况下, future的析构函数是“释放共享状态的最后一个函数”,所以线程完成必须与该函数的返回同步(即发生在该函数之前)。


    我查看了std :: future的文档,发现它是std :: future的析构函数:

    释放任何共享状态。 意即

  • 如果返回对象或提供者持有对其共享状态的最后一个引用,则共享状态将被销毁; 和
  • 返回对象或提供者放弃对其共享状态的引用; 和
  • 这些操作不会阻止共享状态就绪,除非它可能会阻止如果以下所有条件都成立:共享状态是通过调用std :: async创建的,共享状态尚未准备就绪,并且此状态是共享状态的最后一个参考。
  • 注意最后一点。 在我看来,你必须在范围的最后调用get

    链接地址: http://www.djcxy.com/p/5211.html

    上一篇: std::list<std::future> destructor does not block

    下一篇: Run and break an infinite loop using two threads