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

Boost.Asio async_compose高负载下阻塞及版本迁移问题求助

Boost 1.75到1.82迁移后的协程异步代码问题

原Boost 1.75可正常运行的代码

using CompletionTokenType = boost::asio::yield_context;
using FunctionType = void(boost::system::error_code);
using AsyncResultType = boost::asio::async_result<CompletionTokenType, FunctionType>;
using HandlerType = typename AsyncResultType::completion_handler_type;

[[maybe_unused]] ResultOrErrorType
read(CompletionTokenType token, StatementType const& statement)
{
    auto handler = HandlerType{token};
    auto result = AsyncResultType{handler};
    
    auto const future = handle_.get().asyncExecute(statement, [handler](auto const&) mutable {
        boost::asio::post(boost::asio::get_associated_executor(handler), [handler]() mutable {
            handler(boost::system::error_code{});
        });
    });

    result.get(); // suspends coroutine until handler called

    if (auto res = future.get(); res) {
        return res;
    } else {
        // handle error
    }
}

迁移至Boost 1.82后的修改代码

迁移时认为必须改用async_compose/async_initiate,修改后存在以下情况:

  • 传给asyncExecute的回调是可复制的std::function,而self不可复制,因此将self封装为shared_ptr
  • 出现回调嵌套的“回调地狱”,失去了协程原本的顺序性代码结构
[[maybe_unused]] ResultOrErrorType
read(CompletionTokenType token, StatementType const& statement)
{
    auto future = std::optional<FutureWithCallbackType>{};
    
    auto init = [this, &statement, &future]<typename Self>(Self& self) {
        future.emplace(handle_.get().asyncExecute(statement, [sself = std::make_shared<Self>(std::move(self))](auto&& data) mutable {
                auto executor = asio::get_associated_executor(*sself);
                asio::post(executor, [data = std::move(data), sself = std::move(sself)]() mutable {
                    sself->complete(std::move(data));
                });
        }));
    };

    auto res = asio::async_compose<CompletionTokenType, void(ResultOrErrorType)>(init, token, boost::asio::get_associated_executor(token));

    if (res) {
        return res;
    } else {
        // handle error
    }
}

遇到的问题

  1. 新代码多数情况运行正常,但高负载下进入async_compose后会出现阻塞,无错误日志输出;经测试DB代码正常,asyncExecute的回调始终会触发一次
  2. 跨平台差异问题:
    • macOS可正常运行,Linux(gcc)下需给内部post添加显式工作对象否则崩溃
    • macOS可直接调用sself->complete,Linux下则需用post包裹否则崩溃

需求

寻求问题原因及解决思路,若能恢复旧代码的运行方式也可;目前尝试恢复旧代码时发现completion_handler_type似乎已不存在,尽管Boost 1.82文档称仍会暴露该类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 04:53:15