C++std::async-它只是启动线程的语法糖吗



std::futurestd::promisestd::threads

我正试图了解一些较新的C++概念,如std::futurestd::promisestd::async

我想我很清楚未来和承诺是如何运作的。它们是类/对象的副本,可用于以方便的方式向线程传递数据和从线程传递数据。总之,它们是这样工作的:

  • 创建一个promise,定义要返回的数据类型
  • 使用promise.get_future()为创建的承诺创建未来
  • 启动线程,将promise移动到线程函数中
  • 父线程继续做其他工作,直到需要启动线程函数的结果,这时父线程通过调用future.get()来等待结果
  • 如果结果已经是"0";设置";,父线程继续,否则它将休眠一段不确定/无限/无限(?)时间
  • 如果结果不是"0";设置";,子线程继续工作
  • 子线程使用promise.set_value()设置promise值
  • 这会提示父线程在睡眠时唤醒
  • 通常子线程会退出,父线程会调用thread.join()并继续工作

(我最喜欢的例子之一可以在这里找到:https://www.modernescpp.com/index.php/promise-and-future)

因此,promise future构造提供了一种启动线程并返回结果的方法,同时在需要时保持父线程和子线程在程序执行点的同步。

std::async

这就是我感到困惑的地方。我已经阅读了几页关于std::async的文档。让我困惑的是,我通常把futurepromise联系在一起。但是当使用std::async时,在任何时候都没有提到承诺。它被实现隐藏了吗?

以下是一些文档页面:

  • https://en.cppreference.com/w/cpp/thread/async
  • https://www.cplusplus.com/reference/future/async/
  • https://thispointer.com/c11-multithreading-part-9-stdasync-tutorial-example/
  • 为什么我应该使用std::async
  • https://riptutorial.com/cplusplus/example/30411/std--future-and-std--async
  • https://solarianprogrammer.com/2012/10/17/cpp-11-async-tutorial/

据我所知,std::async执行以下操作:

  • 启动线程,返回std::future对象
  • (有不同的启动模式,可以是"延迟",这意味着线程在请求结果之前不会开始工作,"异步"意味着线程立即开始工作)
  • 当需要结果时,调用future.get()
  • 由于这个过程中没有涉及promise,我假设不可能使用future.get()promise返回值
  • 然而,一些示例表明,返回类型是由要使用async调用的函数定义的。然后由future.get()返回该值。所以是否有可能返回一个值,但看不到std::promise

编辑:这是另一篇文章,详细介绍了未来、承诺、异步以及打包任务。它提供了一些解释,解释了为什么您可能会使用不同的选项,但在最后,async和使用future/promise启动线程之间的区别在于,返回值可以在线程函数执行中的任何位置设置,而不仅仅是在最后由return语句设置。

https://ncona.com/2018/02/futures-async-packaged_tasks-and-promises-in-c/

问题

  • 为什么使用async而不是futurepromise
  • async只是在程序员看来隐藏promise的同时启动线程的语法糖吗

换句话说,我的问题是使用async启动单独的线程和显式使用std::threadpromisefuture之间有什么区别。

  • 它们在功能上是一样的吗

为什么要使用async而不是futurepromise对?

因为这是一件事,而不是三件以上的编排。或者是因为您的实现是使用线程池来实现的,而不是每次都使用一个新线程。或者因为您希望deferred实现定义启动策略。

async只是启动线程的语法糖吗?同时在程序员看来隐藏promise

在某些实现中,是的。在其他情况下,它可以在线程池线程上运行该函数。它只需要确保可访问的thread_local数据对于每次调用都是新鲜的。

它们在功能上是一样的吗?

template <typename F, typename... Args>
std::future<std::invoke_result_t<F, Args...>> async(F f, Args... args) {
std::promise<std::invoke_result_t<F, Args...>> prom;
auto fut = prom.get_future();
std::thread([p = std::move(prom)](F f, Args... args) { p.set_value_at_thread_exit(f(args...)); }, f, args...).detach();
return fut;
}

近似std::async的作用是什么?

最新更新