讲师中心 微信公众号
AI工具推荐 视频效率加速

C++ 实现异步任务的任务链式顺序执行模型设计及其 future 异步【源码】

冬萱酱_9330

冬萱酱_9330

发布时间:2026-05-22 21:40:38

|

931人浏览过

|

来源于php中文网

原创

C++标准库不支持原生链式异步任务,std::future仅单次消费且无.then();必须用std::promise手动管理状态、异常传播与执行上下文,自行实现完备的状态机和资源生命周期控制。

c++ 实现异步任务的任务链式顺序执行模型设计及其 future 异步【源码】

如何用 std::future 和 std::promise 构建可链式调用的异步任务

直接说结论:C++ 标准库本身不提供“任务链式顺序执行”的原生抽象,std::future 是单次消费、不可重用的,且不支持 .then() 这类延续操作;强行基于它做链式调度,必须自己封装状态流转和线程调度逻辑,否则会遇到阻塞、重复获取、移动后失效等硬伤。

典型错误现象是:连续写两个 get() 调用,第二个直接抛出 std::future_error: No state;或者把 std::future 存在容器里反复取值,结果第一次取完就崩溃。

  • 每个 std::future 只能调用一次 get() 或 wait()(后者不取值但会消耗状态)
  • 移动构造后的 std::future 会置空原对象,原对象再调用 get() 就报错
  • std::async 默认策略是 std::launch::async | std::launch::deferred,可能延迟执行,导致链式等待逻辑错乱
  • 若想链式触发后续任务,必须在前一个任务完成回调中显式启动下一个——这需要手动管理 std::promise 的 fulfill 时机

为什么不要直接返回 std::future 做链式接口

常见误区是设计类似 task.then([](int x) { return x * 2; }) 的接口,然后内部试图用 std::future::then() ——但 C++20 之前根本不存在这个成员函数,C++20 引入的是 std::experimental::future,非标准且各大编译器支持不一(GCC 12+ 未默认启用,MSVC 需 /std:c++20 + /experimental:module)。

真正可行的路径是:用 std::promise 手动控制完成信号,并把后续任务包装成 lambda,在前序 std::future 的获取点(或线程内)触发。这意味着你得自己解决:

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

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 异常传播:前一个任务抛异常,后续 promise 必须 set_exception(),否则挂起
  • 类型擦除:不同阶段返回类型不同(int → std::string → double),不能只用一个模板参数固定
  • 执行上下文:谁来跑后续 lambda?主线程轮询?新线程?线程池?C++ 标准库不负责这个

一个轻量但可用的链式任务基类实现要点

下面是一个最小可行结构,不依赖第三方库,仅用 C++17:

template<typename T>
class Task {
    std::shared_ptr<std::promise<T>> m_promise;
    std::function<void()> m_work;
<p>public:
explicit Task(std::function<void()> work)
: m_promise(std::make_shared<std::promise<T>>()), m_work(std::move(work)) {}</p><pre class='brush:php;toolbar:false;'>template<typename U>
Task<U> then(std::function<U(T)> f) {
    auto next_promise = std::make_shared<std::promise<U>>();
    auto self = std::make_shared<Task<T>>(*this); // 捕获当前 task 状态
    auto wrapped = [self, f, next_promise]() mutable {
        try {
            T val = self->get(); // 这里会阻塞,仅作示意;实际应走回调机制
            next_promise->set_value(f(val));
        } catch (...) {
            next_promise->set_exception(std::current_exception());
        }
    };
    // 真实项目中这里应投递到线程池或 executor,而非直接调用
    std::thread(wrapped).detach();
    return Task<U>{[next_promise]() { /* 占位,真实由外部驱动 */ }};
}

T get() {
    return m_promise->get_future().get();
}

void start() {
    std::thread([this]() {
        try {
            m_work();
            // 假设 work 内部会调用 m_promise->set_value(...)
        } catch (...) {
            m_promise->set_exception(std::current_exception());
        }
    }).detach();
}

};

注意:then() 里直接 self->get() 是阻塞式写法,仅用于演示逻辑流;生产环境必须改成非阻塞回调注册(例如用 std::future::wait_for 轮询 + 条件变量,或借助 std::jthread + std::stop_token 实现可取消等待)。

最容易被忽略的三个细节

很多实现跑通简单 case 就以为 OK,但在并发压测或异常路径下立刻崩:

  • std::promise 的生命周期必须长于所有对它 get_future() 的使用——如果 Task 对象析构了但还有线程在等它的 future,就会 std::terminate
  • 多个 then() 并发调用同一前置 Task,若没加锁或原子状态判断,可能多次 set_value() 导致未定义行为(std::promise 不允许多次设置)
  • 没有处理 std::future_status::deferred 状态:当 std::async 返回 deferred future 时,wait() 不起作用,必须显式调用 get() 才触发执行

真正健壮的链式任务模型,核心不在语法糖多漂亮,而在 promise 状态机是否完备、异常是否透传、资源是否自动回收——这些都得自己一行行写清楚,标准库只给砖,不给楼。

热门AI工具

更多
Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2248

2024.03.14

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

1019

2024.03.14

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

447

2024.03.14

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

327

2024.03.14

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

426

2024.03.14

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

580

2024.03.14

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

1409

2024.03.21

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

1217

2024.03.22

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn