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
策略,
在这种情况下, future
的析构函数是“释放共享状态的最后一个函数”,所以线程完成必须与该函数的返回同步(即发生在该函数之前)。
我查看了std :: future的文档,发现它是std :: future的析构函数:
释放任何共享状态。 意即
注意最后一点。 在我看来,你必须在范围的最后调用get
。