是否保证为返回void的函数调用std :: async?

tim*_*rau 5 c++ asynchronous c++11 stdasync

我编写了以下代码来测试在Ubuntu std::async()void使用GCC 4.8.2 返回的函数.

#include <future>
#include <iostream>

void functionTBC()
{
    std::cerr << "Print here\n";
}

int main(void)
{
#ifdef USE_ASYNC
    auto i = std::async(std::launch::async, functionTBC);
#else
    auto i = std::async(std::launch::deferred, functionTBC);
#endif
    //i.get();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果i.get();取消注释,则消息"Print here"始终存在; 但是,如果i.get();被注释掉,则"Print here"存在且仅当USE_ASYNC定义时(即,std::launch::async始终导致std::launch::deferred从未打印出消息).

这是保证的行为吗?确保异步调用返回void执行的正确方法是什么?

Yak*_*ont 7

std::launch::deferred意思是"在我.wait()或之前不要运行这个.get()".

从来没有.get().wait()编辑过,它从未跑过.

void 与此无关.

因为std::launch::async,标准规定返回的future的析构函数(~future)将阻塞,直到任务完成(即具有隐式.wait()).这是由MSVC违反了目的,因为他们与设计决定不同意,他们正极力改变标准:在实践中,这意味着你可以不依赖任何行为从根本上std::launch::async恢复future,如果你想将来证明你的代码.

如果没有隐式wait输入~future,如果它在main退出时实际调用了函数,那将是不确定的.它要么发生了,要么不发生.可能你可以通过在结束时使用仍然活动的线程来调用UB main.

您可能想知道有什么用途deferred:您可以使用它来排队计算以进行延迟评估.

  • MSVC 2015的`async` [现在返回阻塞期货](http://blogs.msdn.com/b/vcblog/archive/2014/06/06/c-14-stl-features-fixes-and-breaking-changes- in-visual-studio-14-ctp1.aspx),在提议的更改未能通过完整的委员会. (2认同)