新闻中心

c++如何使用Coroutines TS与Asio结合_c++协程网络编程实践

2025-12-06
浏览次数:
返回列表
使用C++20协程与Asio可简化异步网络编程,通过asio::awaitable和co_await实现同步风格代码。1. 需GCC 10+/Clang 12+并启用-std=c++20;2. Asio 1.20+或Boost.Asio 1.75+支持协程;3. 协程返回类型为asio::awaitable,用co_await等待异步操作;4. co_spawn启动协程并指定执行策略如detached;5. 使用asio::redirect_error避免异常抛出,提升控制粒度;6. 注意避免协程中大栈分配和阻塞调用,应使用asio提供的异步机制。

c++如何使用coroutines ts与asio结合_c++协程网络编程实践

使用 C++ Coroutines TS 与 Asio 进行网络编程,可以极大简化异步操作的编写方式,让异步代码看起来像同步一样清晰。Asio 自 1.20 版本(对应 Boost.Asio 1.75+)开始原生支持 C++20 协程,允许你以现代 C++ 的方式编写高性能异步网络服务。

启用协程支持

确保你的编译环境支持 C++20 并开启协程功能:

  • 使用 GCC 10+ 或 Clang 12+ 编译器
  • 编译选项添加:-std=c++20
  • Asio 需要定义宏:ASIO_ENABLE_HANDLER_TRACKING(可选调试)和确保启用了协程支持(默认已启用)
注意:如果你使用的是 Boost.Asio,需使用 Boost 1.75 及以上版本,并包含头文件时使用 #include <boost></boost>

基本协程返回类型:awaitable

在 Asio 中,协程函数返回类型为 asio::awaitable<t></t>,其中 T 是协程最终返回的值类型(通常为 void)。

一个典型的协程如下:

asio::awaitable<void> echo_session(asio::ip::tcp::socket socket) {
  try {
    char data[1024];
    for (;;) {
      std::size_t n = co_await socket.async_read_some(asio::buffer(data), asio::use_awaitable);
      co_await async_write(socket, asio::buffer(data, n), asio::use_awaitable);
    }
  } catch (const std::exception&) {
    // 客户端断开或出错
  }
}

这里的关键是 co_awaitasio::use_awaitable。它告诉 Asio 以协程方式等待异步操作完成,而不是使用回调函数。

启动协程服务

你需要一个 asio::io_context 来运行事件循环,并通过协程调度任务。

示例服务器主循环:

简小派 简小派

简小派是一款AI原生求职工具,通过简历优化、岗位匹配、项目生成、模拟面试与智能投递,全链路提升求职成功率,帮助普通人更快拿到更好的 offer。

简小派 123 查看详情 简小派
asio::awaitable<void> listen_loop(asio::io_context& ioc, unsigned short port) {
  auto executor = ioc.get_executor();
  asio::ip::tcp::acceptor acceptor(executor, {asio::ip::tcp::v4(), port});

  for (;;) {
    asio::ip::tcp::socket socket = co_await acceptor.async_accept(asio::use_awaitable);
    co_spawn(executor, echo_session(std::move(socket)), asio::detached);
  }
}

int main() {
  asio::io_context ioc{1};

  co_spawn(ioc, listen_loop(ioc, 8080), asio::detached);

  ioc.run();
  return 0;
}

说明:

  • co_spawn 用于启动一个协程,第三个参数指定如何处理协程完成(如 asio::detached 表示不关心结果)
  • co_await acceptor.async_accept(...) 暂停协程直到有连接到来
  • 每个新连接通过 co_spawn 启动独立会话,不会阻塞主监听循环

异常处理与资源管理

协程中抛出的异常会被自动捕获并传递给协程框架。建议在顶层协程中捕获异常,避免崩溃。

改进后的 session:

asio::awaitable<void> echo_session(asio::ip::tcp::socket socket) {
  try {
    char data[1024];
    while (socket.is_open()) {
      auto [e, n] = co_await socket.async_read_some(
          asio::buffer(data), asio::redirect_error(asio::use_awaitable));

      if (e) break; // 客户端关闭

      auto [write_err] = co_await async_write(
          socket, asio::buffer(data, n), asio::redirect_error(asio::use_awaitable));
      if (write_err) break;
    }
  } catch (...) {
    // 处理未预期异常
  }
}

使用 asio::redirect_error 可将错误码转为元组形式返回,避免抛异常,适合精细控制流程。

优势与注意事项

优点:

  • 代码逻辑清晰,无需嵌套回调
  • 局部变量在 co_await 后依然有效,状态保持自然
  • 易于组合多个异步操作(如认证 + 数据读取)

注意事项:

  • 协程栈空间有限,避免在协程中分配大对象(可使用堆或传引用)
  • 不要在协程中调用阻塞函数(如 std::this_thread::sleep_for),应使用 asio::steady_timer
  • 协程生命周期由 co_spawn 管理策略决定,detached 下需确保资源安全释放
基本上就这些。结合 Asio 与 C++ 协程,能写出既高效又易维护的网络服务。不复杂但容易忽略细节,比如错误处理和执行器上下文传递。

以上就是c++++如何使用Coroutines TS与Asio结合_c++协程网络编程实践的详细内容,更多请关注其它相关文章!


# 什么用  # 长宁区网站建设网站制作  # 如何在欧洲推广网站呢  # 网站搭建优化软件有哪些  # 抖音seo店铺  # 网络营销推广与策划  # 微网站建设方案详细  # 兴宁网站优化seo  # 网站怎么授信推广的  # 网络营销怎么做文章推广  # seo流量精灵优化  # 的是  # 前向  # 回调函数  # 抛出  # 头文件  # 随机数  # 如何处理  # 如何使用  # 回调  # red  # 网络编程  # c++  # ai  #   # session 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: Win10磁盘清理工具在哪 Win10打开并使用磁盘清理【教程】  Python实现多节点属性重叠度分析教程  Lar*el表单中优雅地处理“返回”按钮以规避验证:最佳实践指南  Composer中的^和~符号代表什么_精通Composer版本号语义化约束  css子元素高度不一致导致布局错位怎么办_使用align-items:stretch解决高度差异  ArrayList与LinkedList核心操作的Big-O复杂度分析  印象笔记怎样用批量导出备知识库_印象笔记用批量导出备知识库【备份方法】  Python多线程中正确使用sigwait处理SIGALRM信号  QQ邮箱网页版入口登录 QQ邮箱在线邮箱官方通道  在J*a里如何理解依赖关系的方向_依赖方向在模块结构中的作用  深入理解字体排版:Adobe光学字偶距与CSS字偶距的差异与实现  TikTok国际版官网直达_TikTok国际版官网直达进入在线观看  企业名称高精度匹配:N-gram方法在结构相似性分析中的应用  Lar*el如何正确地在控制器和模型之间分配逻辑_Lar*el代码职责分离与架构建议  在J*a项目里如何构建对象之间的契约_接口约束的实际落地  Win10文件资源管理器“此电脑”分组怎么关 Win10恢复经典视图【技巧】  没有大陆身份证/银行卡如何实名微信? 亲测有效的几种方法分享  Win11如何使用Windows Sandbox Win11沙盒功能开启与使用教程【详解】  照顾宝贝2小游戏点击立即在线玩  Composer的 "check-platform-reqs" 命令有什么用_在部署前检查生产环境是否满足Composer依赖需求  将HTML动态表格多行数据保存到Google Sheet的教程  PHP中高效并行检查多链接状态的教程  必由学官网入口 必由学教师登录入口  深入理解Promise链:如何在catch后中断then的执行  汽车之家官方网站官网入口_汽车之家网页版直接进入  反效果?《战地6》免费试玩开启后玩家数不升反降  QQ邮箱官网登录入口 QQ邮箱网页版邮箱快速登录  J*a里如何使用forEach遍历Map_Map遍历方法说明  J*aScript中正确使用querySelectorAll与复杂CSS选择器  Python中高效且防溢出的双曲正弦计算:基于对数空间的优化策略  Win11怎么查看电脑配置_Win11硬件配置检测工具使用  mysql备份恢复性能优化_mysql备份恢复性能优化方法  mcjs网页版在线存档 mcjs云存档登录入口  Python:递归比较文件夹内容并找出特定类型文件的差异  GemBox Document HTML转PDF垂直文本渲染问题及解决方案  2025AO3夸克浏览器通道_AO3手机HTTPS安全入口分享  Golang如何实现Web接口签名验证_Golang Web接口签名校验开发方法  Pandas DataFrame:高效添加条件计算列  在J*a中如何在J*a中使用异常机制记录错误日志_异常日志实践经验  vivo手机互传视频怎么操作_vivo手机互传视频详细传输方法  Python中高效访问嵌套字典与列表中的键值对  AO3网页版最新入口合集 Archive of Our Own在线访问指南  微博网页版怎么开启两步验证_微博网页版账号安全两步验证设置方法  windows10怎么查看硬盘序列号_windows10硬盘id查询命令  12306几点到几点不能订票? | 官方最新系统维护时间全解析  qq游戏跨平台入口_qq游戏多设备同步登录  神庙逃亡小游戏在线玩 神庙逃亡小游戏入口  C++如何实现单例模式_C++设计模式之线程安全的单例写法  黑猫投诉统一入口官网 消费者权益保护投诉平台  sublime怎么预览Markdown渲染效果_Markdown Preview插件 for sublime教程 

搜索