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

C++20协程搭配asio::thread_pool未跨线程分发问题咨询

问题核心原因

串行问题由三个核心错误共同导致:

  • Asio的awaitable默认携带strand执行约束,子协程会继承父协程的strand上下文,同一strand下的协程默认强制串行执行,你没有显式为子协程绑定全局线程池执行器,所有子协程都被限制在run_all()所在的单一线程上下文中调度
  • 你使用的std::this_thread::sleep_for是同步阻塞调用,会直接占住当前运行线程,不会让出执行权给其他协程,即使有空闲线程也不会触发调度切换
  • &&并行等待操作符默认不会自动为子协程做执行器分发,仅会在当前上下文中按顺序启动子协程
修正方案

需要做两处核心调整:

  1. 用Asio内置的异步等待接口替换同步sleep,让协程在等待阶段主动挂起,让出线程资源给其他任务调度
  2. 给每个子协程显式绑定线程池的全局执行器,打破父协程的strand约束,确保子协程可以被分发到不同线程并行执行
修改后的参考代码
#include <asio.hpp>
#include <asio/experimental/awaitable_operators.hpp>
#include <chrono>
#include <iostream>
#include <string>

using namespace std::chrono_literals;
using namespace asio::experimental::awaitable_operators;

asio::awaitable<std::string> one() {
    // 异步等待替代同步阻塞,挂起协程让出线程
    co_await asio::steady_timer(co_await asio::this_coro::executor, 1s).async_wait(asio::use_awaitable);
    std::cout << "one run on thread: " << std::this_thread::get_id() << std::endl;
    co_return "egy";
}

asio::awaitable<std::string> two() {
    co_await asio::steady_timer(co_await asio::this_coro::executor, 1s).async_wait(asio::use_awaitable);
    std::cout << "two run on thread: " << std::this_thread::get_id() << std::endl;
    co_return "ketto";
}

asio::awaitable<std::string> three() {
    co_await asio::steady_timer(co_await asio::this_coro::executor, 1s).async_wait(asio::use_awaitable);
    std::cout << "three run on thread: " << std::this_thread::get_id() << std::endl;
    co_return "harom";
}

asio::awaitable<void> run_all(asio::thread_pool& pool) {
    // 显式为每个子协程绑定全局线程池执行器,打破strand串行约束
    auto [first, second, third] = co_await(
        asio::bind_executor(pool.get_executor(), one()) &&
        asio::bind_executor(pool.get_executor(), two()) &&
        asio::bind_executor(pool.get_executor(), three())
    );
    std::cout << first << " " << second << " " << third << std::endl;
}

int main() {
    asio::thread_pool pool(4);
    co_spawn(pool, run_all(pool), asio::detached);
    pool.join();
    return 0;
}

修改后运行总耗时约1秒,三个协程会被调度到不同线程并行执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:18:04