0

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

// 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)函数,主函数调用是否应该在协程上恢复?还是会自动调用它?

4

2 回答 2

1

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

downloadAsync期望和saveInCacheAsync返回的对象在它们中具有某种机制,以确定一旦它们的异步过程结束,何时何地继续执行协程。表达式(可能)暂停协程的co_await执行,然后访问这些机制,使用该机制调度协程的恢复执行。

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

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

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

于 2021-05-25T14:01:09.333 回答
1

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

另外,co_await 可以暂停协程,但不必这样做(考虑它可能正在“等待”具有空函数体的协程)。它也与调用协程完全不同:可以写

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

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

于 2021-05-25T13:59:33.200 回答