std :: list< std :: future>析构函数不阻塞 [英] std::list<std::future> destructor does not block

查看:728
本文介绍了std :: list< std :: future>析构函数不阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

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

我的印象是让列表 ,应该阻塞,直到所有线程返回其主函数,因为 list s destructor将破坏所有 std :: future 元素和那些的析构函数会等待线程完成。



strong> EDIT:由于它是相关的,我将它添加到这里:
这是在Win7与Visual Studio 2013 Professional MSVC版本
/ EDIT p>

当我尝试这个,它没有阻止,我不得不添加

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

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



我错过了什么,或者我不得不用不同的方式创建线程,做我想做的这里吗?

解决方案

这是 MSVC错误,已修复,但该修复程序将不可用,直到MS发布新版本的Visual C ++,可能在2015年的一段时间。(它也在CTP中为新版本提供,但它是一个漂亮坏主意使用它为任何生产代码...)



正如Scott Meyers在他的博客帖子 std :: future 的析构函数$ c> std :: async 调用使用 launch :: async 策略来阻止,直到生成的线程完成执行(§30.6.8 [futures.async] / p5):


如果实施选择 launch :: async policy,




  • [...]

  • 同步(1.10)
    从成功检测到共享状态的就绪
    状态的第一个函数的返回,或与释放共享状态的最后一个函数的返回
    的返回


在这种情况下, future 的析构函数是释放共享状态的最后一个函数,因此线程完成必须与该函数的返回同步(即发生)。


I have a multithreaded application, with an loop waiting for user input as main thread. On the correct input, it is supposed to stop the loop and wait for all other threads, to end propperly.

For this purpose I created an std::list in which I put the std::future objects created for thread creation

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

I was under the impression, that letting the list run out of scope, should block, until all threads return their main function, because the lists destructor will destrurct all std::future elements and the destructor of those will wait, for the thread to finish.

EDIT: Since it is relevant I will add it here: This is on Win7 with the MSVC version in Visual Studio 2013 Professional /EDIT

When I tried this, it didn't block, I had to add

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

to the end of the function, to block correctly.

Did I missunderstand something, or do I have to create the thread in a different way, to do what I want to do here?

解决方案

This is a MSVC bug that has been fixed, but the fix won't be available until MS releases a new version of Visual C++, probably some time in 2015. (It's also available in the CTP for the new version, but it's a pretty bad idea to use that for any production code...)

As Scott Meyers explained in his blog post, the destructor of a std::future returned by a std::async call using the launch::async policy is required to block until the spawned thread completes execution (§30.6.8 [futures.async]/p5):

If the implementation chooses the launch::async policy,

  • [...]
  • the associated thread completion synchronizes with (1.10) the return from the first function that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first.

In this case, the future's destructor is the "last function that releases the shared state", so the thread completion must synchronize with (i.e., happen before) the return of that function.

这篇关于std :: list&lt; std :: future&gt;析构函数不阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆