c++中实现链式异步任务有五种主流方法:一、用std::future/std::promise构建显式依赖链;二、用std::packaged_task封装可移动任务单元;三、用c++20协程实现原生await链式调用;四、用信号量与原子状态机控制严格时序;五、用事件循环+回调模型实现跨平台调度。

一、基于 std::future 和 std::promise 构建链式异步任务
该方法利用 C++11 标准库中的 std::promise 与 std::future 实现任务间的单向数据传递和状态同步,通过将前一个任务的 std::future 绑定到后一个任务的启动条件,形成显式依赖链。每个节点返回新的 std::future,供后续节点消费。
1、定义模板函数 then,接受一个 std::future
2、在 then 内部构造 std::promise,并使用 std::async 启动异步任务:等待输入 future 就绪后,调用 F 并将结果设置到 promise 中。
3、返回 promise.get_future() 作为链式下一环节的输入源。
二、使用 std::packaged_task 封装可转移异步单元
该方法将每个任务封装为 std::packaged_task
1、声明类型别名 task_t = std::packaged_task
2、创建首个任务,捕获原始输入数据,执行计算后将结果存入局部变量或成员变量中。
3、构造后续任务,以引用方式捕获前序结果变量,并在其内部调用 std::move 转移前序任务的 std::future 或直接访问已就绪值。
4、将所有任务依次提交至线程池或通过 std::thread 手动调度执行。
三、基于协程(C++20)实现原生链式 await 流程
该方法借助 C++20 协程机制,使用 co_await 关键字挂起当前协程直至前置 std::future 或自定义 awaitable 对象就绪,从而以同步风格编写异步逻辑,天然支持多级嵌套链式调用。
1、定义结构体 task,满足可等待协议(拥有 await_ready、await_suspend、await_resume 成员函数)。
2、使 std::future
3、编写返回 task
4、调用协程函数获取 task 对象,再调用其 await_transform 或手动 resume 启动执行流程。
四、采用信号量与原子状态机控制任务流转
该方法不依赖标准库高级异步设施,而是通过 std::atomic
1、初始化一个初始值为 0 的计数信号量 sem_phase 和一个原子整型 current_phase,初值设为 0。
2、每个任务启动前先 sem_phase.acquire(),检查 current_phase.load() 是否等于本任务期望的阶段号;若不符则释放并重试。
3、任务执行完毕后,将 current_phase 原子递增,并对下一阶段对应的信号量执行 release() 操作。
4、所有任务均注册进全局任务数组,由单一调度线程轮询检查各任务就绪条件并触发对应函数指针。
五、基于 event loop + callback 注册模型实现跨平台链式调度
该方法模拟 Node.js 或 libuv 的事件循环机制,将每个异步操作抽象为带唯一 ID 的事件,完成后回调注册函数并将输出绑定至下一个事件的输入槽位,适合需兼容 Windows I/O Completion Port 或 Linux epoll 的跨平台项目。
1、定义结构体 event_node,包含输入缓冲区指针、回调函数指针、输出事件 ID、错误码字段。
2、实现全局单例 event_loop 类,提供 post_event 接口用于插入新事件,并维护就绪队列与待处理队列。
3、每个任务完成时调用 loop.post_event(next_id, result_ptr),其中 next_id 对应下游节点 ID,result_ptr 指向本任务输出数据内存块。
4、在主循环中持续调用 loop.process_once(),从就绪队列取出事件,查找对应节点,执行其回调函数并传入 result_ptr。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











