问题描述
我有一个关于 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)
函数,主函数调用是否应该在协程上恢复?还是会自动调用?
解决方法
C++ 中的协程模型不透明:协程的调用者将其视为一个普通的函数调用,同步返回声明类型的值(这里,{ {1}})。不过,该值只是一个占位符:函数体仅在等待该结果时才执行——但不一定是 future<path>
ed,因为调用者不必是协程(又是不透明度)。
另外,co_await
可能暂停一个协程,但是 need not do so(考虑到它可能在一个带有空函数体的协程上“等待”)。它也与调用协程分离:可以写
co_await
在使用它之前很久就创建占位符。
,co_await
在 C++ 中是一个运算符,就像前缀 *
或其他什么一样。如果您看到 *downloadAsync(...)
,您会期望函数调用发生,然后 *
运算符将对该函数返回的值进行操作。 co_await
也是如此。
downloadAsync
和 saveInCacheAsync
返回的对象应该有一些机制来确定一旦它们的异步进程结束后在何时何地继续执行协程。 co_await
表达式(可能)暂停协程的执行,然后访问这些机制,使用该机制安排协程的执行恢复。
由您的协程函数定义的未来对象返回值旨在能够将 co_return
ed 值从您的函数传送给任何需要它的人。它的工作原理完全取决于您如何为协程编写承诺/未来机制。
处理它的典型方法是能够阻塞请求该值的线程(例如,使用 mutex
),直到异步进程计算该值完成。但它可以做别的事情。事实上,能够在这些事情上co_await
,从而形成长链异步延续来构建更复杂的值,是大多数协程机制的常见部分。
但在某些时候,必须有人实际检索所有这些产生的值。