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

关于Boost Beast Resolver并行处理多个URL解析的疑问

为什么多次调用async_resolve会串行执行而非并行?

核心原因

不是io_context一次只能处理一个解析请求,而是你的代码写法导致了串行执行——使用yield直接获取async_resolve结果时,会同步等待当前解析完成后才会发起下一个请求。

当你写const auto results1 = resolver.async_resolve(..., yield);时,yield会让协程挂起,直到这个DNS解析操作完成才会恢复执行,所以第二个async_resolve要等第一个完全结束才会被调用,自然Wireshark会看到串行的DNS请求。

验证与解决方法

io_context本身支持并发处理多个异步操作,要实现并行解析,需要先一次性发起所有异步请求,再等待所有操作完成。

修改后的示例代码

方式1:先发起所有请求再逐个等待(兼容旧版Boost)

boost::asio::ip::tcp::resolver resolver(io_ctx_);

boost::system::error_code ec1, ec2, ec3;
// 先发起所有异步解析请求,不立即等待完成
auto results1 = resolver.async_resolve(host1_, std::to_string(port1_), yield[ec1]);
auto results2 = resolver.async_resolve(host2_, std::to_string(port2_), yield[ec2]);
auto results3 = resolver.async_resolve(host3_, std::to_string(port3_), yield[ec3]);

// 之后再分别处理每个结果
if (!ec1) { /* 处理results1 */ }
if (!ec2) { /* 处理results2 */ }
if (!ec3) { /* 处理results3 */ }

方式2:用when_all并行等待(Boost 1.78+支持)

boost::asio::ip::tcp::resolver resolver(io_ctx_);

// 用co_spawn启动协程,并行发起所有解析
boost::asio::co_spawn(io_ctx_, [&]() -> boost::asio::awaitable<void> {
    // 同时发起三个解析请求,等待全部完成
    auto [res1, res2, res3] = co_await boost::asio::when_all(
        resolver.async_resolve(host1_, std::to_string(port1_), boost::asio::use_awaitable),
        resolver.async_resolve(host2_, std::to_string(port2_), boost::asio::use_awaitable),
        resolver.async_resolve(host3_, std::to_string(port3_), boost::asio::use_awaitable)
    );

    // 处理三个解析结果
    // ...
}, boost::asio::detached);

io_ctx_.run();

关键结论

  • io_context没有限制同时处理多个DNS解析请求的能力,它可以高效调度多个异步IO操作。
  • 你的串行现象完全是代码逻辑导致的:同步等待单个异步操作完成后才发起下一个,而非并行发起所有请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:46:14