2

考虑以下代码:

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_suspend或在协程之间await_suspend()和之间调用return

Coroutines TSresume只有在协程挂起时才能调用。

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

4

1 回答 1

3

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

5 await-expression 计算 await-ready 表达式,然后: —</p>

(5.1) 如果结果为 false ,则认为协程已挂起。 然后,评估 await-suspend 表达式。如果该表达式的类型为 bool 并且计算结果为 false ,则恢复协程。如果该表达式通过异常退出,则捕获异常,恢复协程,并立即重新抛出异常(15.1)。否则,控制流返回到当前调用者或恢复者(8.4.4)而不退出任何范围(6.6)。——</p>

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

于 2017-08-30T11:33:16.270 回答