什么是C++ 11启动异步任务并忘掉它的方法?

Vio*_*ffe 28 c++ multithreading c++11

我需要这样的东西:

void launch_task()
{
    std::thread([](){ run_async_task(); });
}
Run Code Online (Sandbox Code Playgroud)

除了线程的析构函数将终止我的任务.我不需要对任务进行任何控制,也不需要返回值.它必须运行它,然后线程应该终止并且应该处理C++线程对象.我需要什么C++ 11工具?

我看过了std::async,但找不到我案例的用法示例.它似乎是一个非常复杂的系统,我需要以某种方式存储和操作std::future它或它变得同步(如果我的理解是正确的;我没有找到一篇好的明确文章std::async).

mer*_*011 36

只需在创建后立即分离.

std::thread([](){ run_async_task(); }).detach();
Run Code Online (Sandbox Code Playgroud)

分离后,线程将不再可连接,因此~thread()无效. 这个答案讨论了这种行为的更多细节.

如下面的WB所述,std::async由于以下原因,从此引用中提取不起作用.

如果从std :: async获取的std :: future具有临时对象生存期(未移动或绑定到变量),则std :: future的析构函数将在完整表达式结束时阻塞,直到异步操作完成

  • Lambda在这里是多余的.`的std ::螺纹(run_async_task).detach();` (13认同)
  • @JanickBernet与`std :: async`你不能只是启动并忘记它,因为一旦`std :: future`返回值超出范围,它将阻塞,直到异步函数返回. (6认同)
  • @JanickBernet不幸的是`std :: async`不是很"异步".它实际上阻止了呼叫. (4认同)
  • @JanickBernet,看看[这里](http://en.cppreference.com/w/cpp/thread/async)._如果从std :: async获取的std :: future具有临时对象生存期(未移动或绑定到变量),则std :: future的析构函数将在完整表达式结束时阻塞,直到异步操作完成_ (3认同)
  • 如果其他人对未来从异步阻止破坏创建的原因感兴趣:http://stackoverflow.com/a/23460094/369310 (3认同)
  • @WB:确实如此。Lambda 存在是因为我的实际代码需要它(我正在启动一个带有一些参数的 void 函数,并从我的 `launch_task` 函数的参数中捕获这些参数)。 (2认同)

Mil*_*kic 23

复活一个旧线程,但是有一个巧妙的技巧*如何通过使用来实现“即发即弃”功能std::async,尽管std::future它返回了阻塞。主要成分是返回的共享指针,std::future该指针在 lambda 中按值捕获,导致其引用计数器递增。这样,在std::futurelambda 完成其工作之前不会调用的析构函数,根据需要提供真正的异步行为。

template <class F>
void call_async(F&& fun) {
    auto futptr = std::make_shared<std::future<void>>();
    *futptr = std::async(std::launch::async, [futptr, fun]() {
        fun();
    });
}
Run Code Online (Sandbox Code Playgroud)

*感谢我的同事和真正的 C++ 专家 MVV,他向我展示了这个技巧。

  • @violetgiraffe 它与 std::thread{..}.detach() 做同样的事情,但我在很多地方读到,用 std::async 不可能实现相同的目标,这个答案反驳了这一点。关于性能,Kurt Guntheroth 发现创建线程比使用异步要昂贵 14 倍(请参阅 https://www.amazon.com/Optimized-Proven-Techniques-Heightened-Performance/dp/1491922060/)。因此,与此相比,少量额外 CPU 周期和额外内存分配的成本可以忽略不计(不过,应该进行测量)。 (6认同)
  • 这种技术将线程管理问题推迟到操作系统,这可能会比您的应用程序做得更好。例如,如果“std::async”的实现在后台使用 Grand Central Dispatch 或其他一些线程管理系统,则您可以免费利用这些功能,而不是为“N”异步任务旋转“N”线程,并有超额认购机器的风险。 (4认同)