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

Boost协程执行async_write后无法恢复,如何检测状态并重启?

Boost.Coroutine异常状态检测与自动重启方案

核心问题分析

你的代码存在几个潜在问题,也是导致协程静默挂起/退出的原因:

  • 未处理异步操作的错误码,当socket写入或定时器等待出错时,协程可能进入异常路径或静默退出
  • 未捕获协程内的异常,一旦出现未处理异常,协程会直接销毁,且不会有任何提示
  • io_service.run()在无任务时会返回,未调用reset()导致后续无法处理新任务

解决方法:异常捕获+自动重启

通过给协程添加异常捕获逻辑,并在协程结束时自动重启,即可解决随机挂起问题。同时处理异步操作的错误码,避免静默失败。

修改后的完整代码

#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/system/error_code.hpp>
#include <boost/chrono.hpp>

boost::asio::io_service io_service;
boost::asio::ip::tcp::socket* socket_;
boost::asio::steady_timer timer{io_service};
// 假设buffer是已定义的全局缓冲区,比如char buffer[1024];

void write_to_socket(boost::asio::yield_context yield_context)
{
    try {
        while(true){
            boost::system::error_code ec;
            // 执行异步写入
            socket_->async_write_some(boost::asio::buffer(buffer), yield_context[ec]);
            if (ec) {
                std::cerr << "写入错误: " << ec.message() << std::endl;
                break; // 退出循环,触发协程重启
            }
            std::cout << "Done, now sleep for 10 ms" << std::endl;    
            // 定时器等待
            timer.expires_from_now(boost::chrono::milliseconds(10));
            timer.async_wait(yield_context[ec]);
            if (ec) {
                std::cerr << "定时器等待错误: " << ec.message() << std::endl;
                break;
            }
        }
    } catch (const std::exception& e) {
        std::cerr << "协程异常: " << e.what() << std::endl;
    } catch (...) {
        std::cerr << "协程未知异常" << std::endl;
    }
    // 协程结束后自动重启
    boost::asio::spawn(io_service, &write_to_socket);
}

int main ()
{
    // 此处需补充socket初始化与连接逻辑
    // socket_ = new boost::asio::ip::tcp::socket(io_service);
    // boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 8080);
    // socket_->connect(ep);

    // 启动第一个协程
    boost::asio::spawn(io_service, &write_to_socket);
    while(true){
        io_service.run();
        io_service.reset(); // 重置io_service,确保下次run能处理新任务
    }
}

关键细节说明

  1. 异常捕获:在协程函数内添加try-catch块,捕获所有可能的异常,避免协程因未处理异常静默销毁。
  2. 错误码处理:每个异步操作后检查错误码,当出现错误时主动退出循环,触发协程重启。
  3. 自动重启:在协程函数末尾重新调用boost::asio::spawn,无论协程是正常退出还是异常退出,都会自动生成新的协程。
  4. io_service重置:io_service.run()在无任务时会返回,调用reset()可以重置内部状态,确保后续run()能处理新的协程任务。

协程状态检测(可选)

如果需要主动检测协程是否活跃,可以通过yield_context获取coroutine_handle:

auto handle = yield_context.native_handle();
if (!handle.is_valid()) {
    // 协程已销毁,执行重启逻辑
    boost::asio::spawn(io_service, &write_to_socket);
}

但实际场景中,自动重启的方式更简洁可靠,无需主动轮询检测。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:45:12