协程在final-suspend之后的状态



协程有一个初始挂起点和一个最终挂起点。当coroutine_handle在最终挂起点挂起时,它就是done。然而,这种悬浮是通过co_await promise.final_suspend()完成的。此函数可以返回std::never_suspend或类似的可等待对象。

所以…然后会发生什么?如果协程在最终挂起点挂起,coroutine_handle::resume会产生UB,但是如果超过最终挂起点会发生什么?

可以推测,协程不会被认为挂起,因此根据该规则resume是UB。但是,对于超过最后挂起点的协程句柄,您可以做些什么呢?

或者让final_suspend返回std::suspend_always以外的任何值都没有意义吗?

协程函数是通过协程主体的转换来定义的。协程主体完成并退出后(通过co_return或在块的末尾运行),将出现以下代码:

co_await p.final_suspend();
//destruct promise p
//destruct parameters in coroutine frame
//destroy coroutine state

其中p是协程的promise对象。因此,如果final_suspend没有引起co_await的挂起,则承诺被销毁,随后是协程帧的参数,然后是协程状态对象本身。

coroutine_handle引用协程状态。如果它已被销毁,则句柄不会引用挂起的协程(因为没有协程)。因此,resume将具有未定义的行为。如果句柄没有挂起(因为它不是句柄),done类似地具有UB。

最新更新