0

0

c++20的协程(Coroutine)如何简化异步编程? (对比传统回调)

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-12 15:27:16

|

880人浏览过

|

来源于php中文网

原创

协程不能自动简化异步编程,它仅提供挂起/恢复机制,不内置调度、线程管理或运行时支持,需手动处理生命周期、避免栈变量跨挂起、显式捕获异常并依赖第三方库实现awaitable语义。

c++20的协程(coroutine)如何简化异步编程? (对比传统回调)

协程不能自动简化异步编程,它只是把回调地狱换成了「看似同步、实则挂起」的控制流——前提是正确管理生命周期、避免溢出、不滥用 co_await 在非可挂起点。

为什么 co_await 不等于「自动异步转同步」

协程本身不执行调度,也不绑定线程或事件循环。你写 co_await async_read(socket, buf),背后仍需一个实现了 awaitable 接口的对象(比如返回 task 的函数),而该对象的 await_suspend 才真正注册回调到 I/O 多路复用器(如 epoll 或 IOCP)。

常见误判是以为只要用了 co_await,就能像 Python 的 async/await 那样开箱即用。C++20 没有标准运行时,所有调度逻辑必须自己搭或依赖第三方库(如 libunifex、cppcoro、Boost.ASIO 1.78+)。

  • co_await 只触发挂起/恢复协议,不启动任何线程、不管理线程池
  • 没有 asyncio.run() 对应物;你得手动调用 task.start()executor.run()
  • 忘记 co_return 或在销毁前未完成协程,会导致未定义行为(UB),而非抛异常

对比传统回调:代码结构变了,但错误点更隐蔽

传统回调的问题是嵌套深、错误传播难、状态分散;协程表面扁平,但引入了新的崩溃路径:

立即学习C++免费学习笔记(深入)”;

AI Cheat Check
AI Cheat Check

专为教授、教师和大学提供的AI作弊检测,以验证学生作业的真实性

下载
task handle_request(tcp_socket& sock) {
    auto buf = std::make_unique(1024);
    // ✅ 正确:buf 生命周期覆盖整个协程
    ssize_t n = co_await sock.async_read(buf.get(), 1024);
    co_await sock.async_write("HTTP/1.1 200 OK\r\n", 18);
}

下面这段就危险:

task bad_example(tcp_socket& sock) {
    char local_buf[1024]; // ❌ 栈变量,协程挂起后可能已被销毁
    co_await sock.async_read(local_buf, 1024); // UB 高发区
}
  • 协程栈帧在挂起时被移到堆上(由 promise_type::get_return_object_on_allocation 决定),但局部变量仍是栈分配 —— 必须确保其生命周期跨挂起点
  • 异常仍需手动捕获:try { co_await op(); } catch(...) { ... },不会自动传播到调用方协程
  • 调试困难:gdb 对 co_await 行的单步支持有限,常跳过挂起点直接到恢复点

哪些场景下协程确实比回调更可靠?

当异步操作有明确顺序依赖、且中间状态需多次复用时,协程优势明显。例如实现一个带重试、超时、进度通知的文件下载:

task download_with_retry(http_client& client, string_view url) {
    for (int i = 0; i < 3; ++i) {
        auto res = co_await client.get(url); // 等待完整响应
        if (res.status == 200) {
            co_await write_to_disk(res.body);
            co_return true;
        }
        co_await timer::sleep(1s); // 挂起而不阻塞线程
    }
    co_return false;
}
  • 相比回调嵌套(on_success → on_write_complete → on_timeout),状态变量(重试次数、临时 buffer)自然保留在作用域
  • 超时可统一用 co_await with_timeout(op, 5s) 封装,无需为每个回调单独设 timer ID 并清理
  • 但注意:timer::sleep 必须是真正的 awaitable(内部调用 epoll_waitWaitForSingleObject),不是 std::this_thread::sleep_for

协程最大的陷阱不是语法,而是误以为它解决了资源生命周期问题——它恰恰让生命周期更难追踪。栈变量、裸指针、未 move 的 unique_ptr,在挂起点前后都可能失效。写协程代码时,眼睛要盯着「这个变量在下次 co_await 返回时还活着吗?」,而不是只看缩进是否整齐。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

748

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

634

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

758

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1261

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

577

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

705

2023.08.11

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

10

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 3万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号