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

时间:2017-08-15 15:17:43

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

请考虑以下代码:

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

此处worker_thread可以在协程仍然执行h.resume();await_suspendawait_suspend()之间调用return

Coroutines TS表示只有在协程被暂停时才能调用resume

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

1 个答案:

答案 0 :(得分:3)

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

  

5 await-expression计算await-ready表达式,然后: -

     

(5.1)如果结果为false,则认为协程已暂停。然后,将评估await-suspend表达式。如果   该表达式的类型为bool,并且计算结果为false,即coroutine   恢复了。如果该表达式通过异常退出,则为异常   被捕获,协程恢复,并立即例外   重新抛出(15.1)。否则,控制流程返回到当前   呼叫者或呼叫者(8.4.4),不退出任何范围(6.6)。 -

所以你可以从另一个线程恢复协同程序,只要你保证退出await-suspend不会导致双重恢复或破坏协程