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

Is std::async guaranteed to be called for functions returning void?

我已经编写了以下代码来测试 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(); 被注释掉,当且仅当 USE_ASYNC 被定义时 "Print here" 存在(也就是说, std::launch::async 总是导致打印出消息,而 std::launch::deferred从来没有)。

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

std::launch::deferred 表示 "do not run this until I .wait() or .get()".

因为您从未 .get().wait() 编辑过,所以它永远不会 运行。

void与此无关

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

~future中没有隐含的wait,它是否在main退出时实际调用了该函数将是不确定的。它要么发生,要么不发生。可能你可以通过在 main.

末尾有仍然活跃的线程来调用 UB

你可能想知道 deferred 有什么用:你可以用它来排队计算以进行惰性计算。