从VS2013到VS2017,std :: async不会启动新线程

时间:2017-06-29 15:18:25

标签: c++ multithreading c++11 asynchronous

我从2013年到2017年更新了我的Visual Studio。 编译很好,但似乎std :: async调用没有打开一个新线程。 (我在调试时无法在线程窗口中看到一个新的。也看起来调用异步函数的线程完成了这项工作......)

那是我的函数调用:

Out-File

我没有更改代码中的任何内容,在VS2013中,一切正常。

任何想法?谷歌不能告诉我很多关于这一点,但也许我有错误的关键字。所以关键字也会有所帮助!

谢谢

4 个答案:

答案 0 :(得分:7)

您需要保留std::future返回的async,否则临时的析构函数将阻止,直到工作完成。

auto t = std::async(std::launch::async, myfunction, this);

答案 1 :(得分:6)

在VS2013中,std::async不遵守C ++标准。

存在分歧,致力于MSVC的开发人员希望std::future std::future的行为与其他std::future一样。

标准不同意。

他们在2013年发布了非标准合规std::future。2015年如果我没记错,他们就开始遵循标准。

该标准规定std::async( std::launch::async拥有由future生成的共享状态的析构函数将阻塞,直到任务完成。

这是因为,在实践中,悬挂线程对于以可预测的方式运行的程序是不利的。

您现在负责拥有并坚持从

返回的auto f = std::async(std::launch::async, myfunction, this);
f.wait

f.getstd::future<?>当你需要它准备就绪时。

这可能需要更改代码的工作方式;例如,保持期货的向量(如果你有多个),或者将this成员添加到std::async并存储它(这也可以确保异步调用不会过时)对象的生命周期!)。

作为第二个注释,Windows上的async也使用有界线程池;如果有超过一定数量的std::thread任务处于活动状态,则可能无法启动新任务。

他们有计划修复它(因为它违反标准中的建议),但此时我仍然建议使用std::async,如果你需要thread_pool类似的行为来实现类似的东西自己。

我个人的倾向是创建具有特定数量的std::thread s的特定于问题的future,但是让您排队任务并获取{{1}} s(使用自定义扩展程序)我从它那里得到了非常有限的延续能力。

这使得线程所有权和依赖关系更加明确,并避免处理仍然存在的MSVC非标准兼容怪癖。

答案 2 :(得分:0)

看起来std :: async正在回归结束。所以,如果你简单地调用它,就不能异步工作。

std::async(std::launch::async, myfunction, this);

Key定义了一个答案:myfunction必须返回std :: future,你需要定义和响应相同的类型。

std::future<int> foo = std::async(std::launch::async, myfunction, this);

如果你在构造函数中调用std :: async,foo必须是该类的成员。

class MyClass {
    //Your code
    private:
        std::future<int> exitThread;
}

而且,当你调用std :: async时必须

exitThread = std::async(std::launch::async, myfunction, this);

答案 3 :(得分:0)

非常简单的解决方案:

std::thread t(myfunction, this);
t.detach();