我已经编写了以下代码来测试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
的正确方法是什么?
答案 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
有什么用途:您可以使用它来排队计算以进行延迟评估。