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

使用Boost ASIO通道实现协程取消时出现段错误求助

问题分析与修复

核心问题:通道生命周期导致的悬空引用

coroutine_manager中创建的通道ch是局部shared_ptr,当co_await (to_be_cancelled(*ch, io_ctx) && send_one_message(*ch))完成时(比如send_one_message先执行完毕),coroutine_manager协程结束,ch的引用计数归零被销毁。但此时to_be_cancelled协程仍持有通道的引用end,访问已销毁的通道对象会触发段错误。

其他潜在问题

  • send_one_message协程未co_await async_send的结果,导致协程提前退出,可能引发未定义行为。
  • 代码中混用io_service和io_context(两者是别名,但统一使用新的io_context更规范)。

修复后的代码

#include <boost/asio.hpp>
#include <boost/asio/experimental/concurrent_channel.hpp>
#include <memory>
#include <iostream>
#include <string>

using namespace boost::asio;
using namespace std;

awaitable<void> to_be_cancelled(
    shared_ptr<experimental::concurrent_channel<void(system::error_code, string)>> end,
    shared_ptr<io_context> io_ctx)
{
    ip::tcp::socket sock(*io_ctx);
    ip::tcp::endpoint endpoint(ip::tcp::v4(), 8000);
    ip::tcp::acceptor acceptor(*io_ctx, endpoint);
    
    co_await (
        end->async_receive(use_awaitable_t()) ||
        acceptor.async_accept(sock, use_awaitable_t())
    );

    cout << "done\n";
}

awaitable<void> send_one_message(
    shared_ptr<experimental::concurrent_channel<void(system::error_code, string)>> channel)
{
    co_await channel->async_send(system::error_code{}, string("hello"), use_awaitable_t());
}

awaitable<void> coroutine_manager(shared_ptr<io_context> io_ctx)
{
    auto ch = make_shared<experimental::concurrent_channel<void(system::error_code, string)>>(*io_ctx, 5);
    // 用shared_ptr传递通道,延长其生命周期至所有使用它的协程结束
    co_await (to_be_cancelled(ch, io_ctx) && send_one_message(ch));
}

int main()
{
    auto io_ctx = make_shared<io_context>(2);
    co_spawn(*io_ctx, coroutine_manager(io_ctx), detached);
    io_ctx->run();
}

修复要点

  • 将通道的传递从引用改为shared_ptr,确保所有使用通道的协程都持有共享所有权,直到协程全部结束,避免悬空引用。
  • 在send_one_message中添加co_await,等待async_send操作完成,保证协程行为的确定性。
  • 统一使用io_context替代混用的io_service,代码更规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:40:50