You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用resume后,std::coroutine_handle::done为何始终返回false?

C++协程coroutine_handle::done()返回false的原因及解决方法

我编写了一个用于理解基础的简单C++协程示例,但无法理解为何coroutine_handle对象的done()方法仍返回false。我已调用resume,且后续没有更多co_await语句。以下是我的代码:

#include <coroutine>
#include <iostream>


struct ReturnObject {
    struct promise_type {
        ReturnObject get_return_object() {
            return {std::coroutine_handle<promise_type>::from_promise(*this)};
        }
        std::suspend_never initial_suspend() noexcept { return {}; }
        std::suspend_never final_suspend() noexcept { return {}; }
        void unhandled_exception() {}
        void return_void() noexcept {}
    };
      
    ReturnObject(std::coroutine_handle<> h) : h_{h}{ } 

    std::coroutine_handle<> h_; 
};

ReturnObject foo() {
    std::cout << "1. Hello World!\n";
    co_await std::suspend_always{};
    std::cout << "2. Hello World!\n";
}

int main(int argc, char** argv) {
    ReturnObject ret_object = foo();
    ret_object.h_();
    std::cout << ret_object.h_.done() << std::endl;
    return 0;
}

调用resume后已无更多co_await,但done()方法始终返回false,请问我忽略了什么?

问题根源

问题出在promise_type中的final_suspend()函数:

  • 当协程执行完所有代码(即foo()中的2. Hello World!输出后),会调用return_void(),随后进入final_suspend()阶段。
  • 你当前返回的是std::suspend_never,这意味着协程会立即销毁自身,而不是挂起。此时coroutine_handle变成了悬空句柄,调用done()属于未定义行为,你看到的false是这种未定义行为的表现。
  • coroutine_handle::done()返回true的前提是:协程处于挂起状态(包括挂起在final_suspend点)。如果协程已经被销毁,句柄不再有效,done()的返回值没有意义。

解决方法

修改promise_type的final_suspend(),让它返回std::suspend_always,这样协程执行完毕后会挂起在final_suspend点,此时done()会正确返回true。同时,你需要手动调用coroutine_handle::destroy()来销毁协程,避免内存泄漏:

修改后的代码:

#include <coroutine>
#include <iostream>


struct ReturnObject {
    struct promise_type {
        ReturnObject get_return_object() {
            return {std::coroutine_handle<promise_type>::from_promise(*this)};
        }
        std::suspend_never initial_suspend() noexcept { return {}; }
        // 将final_suspend改为返回suspend_always
        std::suspend_always final_suspend() noexcept { return {}; }
        void unhandled_exception() {}
        void return_void() noexcept {}
    };
      
    ReturnObject(std::coroutine_handle<> h) : h_{h}{ } 

    std::coroutine_handle<> h_; 
};

ReturnObject foo() {
    std::cout << "1. Hello World!\n";
    co_await std::suspend_always{};
    std::cout << "2. Hello World!\n";
}

int main(int argc, char** argv) {
    ReturnObject ret_object = foo();
    ret_object.h_();
    std::cout << std::boolalpha << ret_object.h_.done() << std::endl; // 现在会输出true
    ret_object.h_.destroy(); // 手动销毁协程,避免内存泄漏
    return 0;
}

补充说明

  • std::boolalpha用于让输出显示true/false而不是1/0,方便查看结果。
  • 如果你坚持使用std::suspend_never作为final_suspend的返回值,那么协程会在执行完后立刻销毁,此时绝对不能再使用对应的coroutine_handle(包括调用done()),否则会触发未定义行为。

内容的提问来源于stack exchange,提问作者Cabbas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 08:22:37