(重新)调用协程和等待它有什么区别?



我进入协同例程的时间已经晚了;但现在C++20已经有了它们,可以说我是在冒险。具体来说,我看了Timur Doumler在CppCon20演讲中关于协同活动的片段。

Timur首先解释了带有函数和协程(或者更确切地说,协程和相关生成器(的协同例程的使用:

my_generator<int> f() {
int i = 0;
while (true)
co_yield i++;
}
void foo() {
auto g = f();
std::cout << g() << 'n';
std::cout << g() << 'n';
std::cout << g() << 'n';
}

在本节的后面,他介绍了co_await,并举例说明:

async_generator<T> f1() { 
// code
auto u = co_await f2();
// more code
co_return u;
}
async_generator<U> f2() {
// code
co_yield u;
}

现在,我不明白的是,第二个例子与第一个例子中的调用协同程序有何不同,例如:

async_generator<T> f1() {
auto g2 = f2();
// code
auto u = g2();
// more code
co_return u;
}
async_generator<U> f2() {
// code
co_yield u;
}

我试着在cppreference上查找co_await,这是存在的,但它链接到了通用协同程序页面,老实说,我从树上看不到森林。我宁愿暂时不知道所有的细节。我只是想了解高层次的概念差异。

co_yield语句只有在存在挂起上下文时才有意义。生成器的挂起上下文的一个示例是在循环中使用coyield(为某些条件生成值(。

在本例中:

async_generator<T> f1() { 
// code
auto u = co_await f2();
// more code
co_return u;
}
async_generator<U> f2() {
// code
co_yield u;
}

coyeild与任何挂起上下文都没有关联,因此它将作为一个典型的函数工作(即coyield被解释为一个正常的返回语句(。auto u将等待,直到f2到达函数的末尾,从而使执行工作为典型的函数调用语义。

在本例中:

async_generator<T> f1() {
auto g2 = f2();
// code
auto u = g2();
// more code
co_return u;
}
async_generator<U> f2() {
// code
co_yield u;
}

同样,由于缺少promise对象的创建和操作,因此缺少挂起上下文。因此,该代码的工作方式与前面的示例完全相同。

然而,如果这些例子因悬浮上下文而不同,那么共屈服可能会有不同的效果。

这里有关于协例程和promise对象之间交互的权威解释(使用coawait和coyield(。

最新更新