【问题标题】:What's the difference between (re)invoking a coroutine and awaiting it?(重新)调用协程和等待它有什么区别?
【发布时间】:2021-02-14 13:54:54
【问题描述】:

我进入协同程序已经很晚了;但是现在 C++20 有了它们,可以这么说。具体来说,我观看了 Timur Doumler 在this CppCon20 talk 中关于协程的片段。

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;
}

我尝试寻找co_await on cppreference,它确实存在,但是 - 它链接到一般的coroutines page - 老实说,我无法从树上看到森林。我宁愿不知道所有的细节——现在。我只是想了解高层次的概念差异。

【问题讨论】:

  • 没有重新调用f;调用它返回的生成器对应于执行co_await,但显然它的不同之处不仅在于它在每次协程执行时发生多次,而且还在于它不能挂起调用者。
  • @DavisHerring:“重新调用”只是一个比喻。不管怎样——调用一个函数; co_awaiting 一个协程;调用生成器 - 所有这些都会暂停调用者,直到返回某些内容。

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


【解决方案1】:

co_yield 语句仅在存在 暂停上下文 时才有意义。生成器的暂停上下文的一个示例是在循环中使用 co_yield(为某些条件产生一个值)。

在这个例子中:

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

async_generator<U> f2() {
  // code
  co_yield u;
}

co_yeild 不与任何暂停上下文相关联,因此它可以作为典型函数工作(即,co_yield 被解释为正常的返回语句)。 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 对象的创建和操作,因此缺少暂停上下文。因此,代码的工作方式与前面的示例完全相同。

但是,如果示例因暂停上下文而异,那么 co_yield 的工作方式可能会有所不同。

协同例程和promise-objects(使用co_await和co_yield)交互的权威解释见here

【讨论】:

  • 1.我不认为这实际上回答了我的问题。 2. 他们不是我的榜样。 3. 我希望得到一个不需要我了解承诺对象的解释(除非你告诉我必须理解它们)。
  • 我稍微改变了措辞以反映第 2 点。Afaik,老实说,我相信 promise 对象与所​​有现代语言(如 python、c# 和 c++)中的异步编程相关联。一些 C 中的微处理器编程可以通过利用固有的硬件布局来放弃 promise-object 抽象。但是,afaik 是一种高级编程语言模型,它使用 Promise 对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-27
  • 2012-05-22
  • 1970-01-01
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多