C++20协程中coroutine_handle.done()返回异常导致循环无法退出的问题求助
C++20协程中coroutine_handle.done()返回异常导致循环无法退出的问题求助
嗨,我来帮你排查这个问题~你的代码里有两个关键问题导致了循环无法正确退出还出现运行时错误:
1. final_suspend的返回类型错误
你在promise_type里定义的final_suspend返回了std::suspend_never,这意味着当协程执行完最后一个co_yield、走到函数末尾时,会立即销毁协程帧。此时你手里的coroutine_handle就变成了悬空句柄,后续调用done()或resume()都会触发未定义行为,也就是你遇到的运行时错误。
正确的做法是让final_suspend返回std::suspend_always,这样协程执行完逻辑后会保持挂起状态,直到你显式调用destroy()来释放资源:
std::suspend_always final_suspend() noexcept { return {}; }
2. 循环的执行顺序逻辑错误
原代码里你先调用GetValue()再resume(),但第一次进入循环时,协程还没执行到任何co_yield,此时m_value是未初始化的状态,取值行为本身就有问题。而且当协程完成后,悬空的句柄会导致done()的判断失效。
调整后的main函数应该先resume()让协程执行到co_yield挂起,再取值,同时最后要显式销毁协程帧:
int main() { ReturnObject range = Range(1,10,3); auto handle = range.Handle(); while (!handle.done()) { handle.resume(); // 先让协程执行到挂起点或完成 if (!handle.done()) // 确认协程未完成再取值 { std::cout << range.GetValue() << std::endl; } } handle.destroy(); // 显式销毁协程帧,释放资源 }
补充说明
当协程执行完Range里的循环后,会调用return_void(),接着进入final_suspend挂起,此时handle.done()会返回true,循环就会正常退出,最后调用destroy()就能安全清理协程的资源啦。
备注:内容来源于stack exchange,提问作者SZYoo
相关产品推荐
相关产品推荐

