【问题标题】:Is it required to resume co-routine from the calling function in C++?是否需要从 C++ 中的调用函数恢复协程?
【发布时间】:2021-08-13 16:44:25
【问题描述】:

我有一个关于 co_await 在 C++ 中的工作的问题。我有以下代码 sn-p:-

// Downloads url to cache and
// returns cache file path.
future<path> cacheUrl(string url)
{
 cout << "Downloading url.";
 string text = co_await downloadAsync(url); // suspend coroutine
 cout << "Saving in cache.";
 path p = randomFileName();
 co_await saveInCacheAsync(p, text); // suspend coroutine
 co_return p;
}

int main(void) {
  future<path> filePath = cacheUrl("https://localhost:808/");
  
  return 0; 
}

co_await 关键字用于暂停任何协程的执行。我们在上面的代码中有 2 个使用它的实例。在主函数中,我们可以访问协程。当程序执行co_await downloadAsync(url) 行时,它会调用downloadAsync 还是暂停协程。 另外,为了执行下一个saveInCacheAsync(p, text) 函数,主函数调用是否应该在协程上恢复?还是会自动调用?

【问题讨论】:

    标签: c++ c++20 coroutine c++-coroutine boost-coroutine


    【解决方案1】:

    co_await 在 C++ 中是一个运算符,就像前缀 * 或其他什么。如果您看到*downloadAsync(...),您会期望函数调用发生,然后* 运算符将作用于该函数返回的值。 co_await 也是如此。

    downloadAsyncsaveInCacheAsync 返回的对象应该有一些机制来确定在它们的异步进程结束后何时何地继续执行协程。 co_await 表达式(可能)暂停协程的执行,然后访问这些机制,使用该机制调度协程的恢复执行。

    由你的协程函数定义的未来对象返回值意味着能够将co_returned 值从你的函数传给任何需要它的人。其运作方式完全取决于您如何为协程编写承诺/未来机制。

    处理它的典型方法是能够阻塞请求该值的线程(例如,使用mutex),直到异步进程计算该值完成。但它可以做其他事情。事实上,能够在这些事情上co_await,从而形成异步延续的长链来构建更复杂的值,是大多数协程机制的常见部分。

    但在某些时候,必须有人实际检索所有这些产生的值。

    【讨论】:

      【解决方案2】:

      C++ 中的协程模型是不透明的:协程的调用者将其视为普通函数调用,同步返回声明类型的值(这里,@ 987654322@)。不过,该值只是一个占位符:函数体仅在等待该结果时执行——但不一定是co_awaited,因为调用者不必是协程(又是不透明度)。

      另外,co_await 可能暂停一个协程,但 need not do so(考虑它可能正在“等待”具有空函数体的协程)。它也与调用协程完全分开:可以写

      auto cr=coroutine(…);
      do_useful_work();
      co_await cr;
      

      在使用它之前创建占位符。

      【讨论】:

        猜你喜欢
        • 2012-04-21
        • 2017-06-03
        • 2012-09-01
        • 2020-10-15
        • 2023-04-07
        • 2017-04-21
        • 1970-01-01
        • 2019-12-17
        • 1970-01-01
        相关资源
        最近更新 更多