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

时间:2015-05-29 16:52:07

标签: c++ c++11 asynchronous stdasync

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

#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;
}

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

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

1 个答案:

答案 0 :(得分:8)

std::launch::deferred表示“在.wait().get()”之前不要运行此操作。

由于您从未.get().wait()编辑,因此它从未运行过。

void与此无关。

对于std::launch::async,标准规定返回的future的析构函数(~future)将阻塞,直到任务完成(即具有隐式.wait())。 MSVC故意违反这一规定,因为他们不同意该设计决定,并且他们正在努力改变标准:在实践中,这意味着您不能依赖std::launch::async返回future的任何行为。如果你想为你的代码提供面向未来的证明。

如果wait中没有隐式~future,如果main退出时实际调用了该函数,那么它将是不确定的。它要么发生了,要么不发生。可能你可以通过main末尾的仍处于活动状态的线程来调用UB。

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