我可以在await_suspend期间调用coroutine_handle::恢复吗?

Can I call coroutine_handle::resume during await_suspend?

本文关键字:handle 恢复 coroutine await suspend 我可以 调用      更新时间:2023-10-16

请考虑以下代码:

coroutine_handle<> g_handle;
atomic<int> g_ready;
void worker_thread() {
if (++g_ready == 2) g_handle.resume();
}
struct Awaitable {
bool await_ready() const { return false; }
bool await_suspend(coroutine_handle<> h) {
g_handle = h;
if (++g_ready == 2) return false;
// worker_thread can call h.resume() at this point
return true;
}
void await_resume() {}
};
Future coroutine() {
Awaitable a;
std::thread(worker_thread).detach();
co_await a; // compiles as:
// if (a.await_suspend(h)) {
//   // worker_thread can call h.resume() at this point
//   return;
// }
}

在这里,当协程仍在await_suspend或协程中的await_suspend()return之间执行时,worker_thread可以调用h.resume();

协程TS 表示,只有在协程挂起时才能调用resume

在执行await_suspend期间是否被视为暂停?

是的,链接的协程 TS 的文本指出,5.3.8 第 3-5 段。强调我的:

5 等待表达式计算等待就绪表达式,然后: —

(5.1( 如果结果为假,则协程被视为暂停。然后,计算等待挂起表达式。 如果 该表达式的类型为 bool 并计算为 false ,协程 已恢复。如果该表达式通过异常退出,则异常 被捕获,协程恢复,异常立即被捕获 重新抛出 (15.1(。否则,控制流返回到当前 调用方或恢复器 (8.4.4(,而不退出任何作用域 (6.6(。—

因此,您可以从另一个线程恢复协程,只要您保证退出等待挂起不会导致双重恢复或协程破坏