导读:本期聚焦于小伙伴创作的《C++如何用std::future与promise实现异步任务链式调用执行逻辑》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++如何用std::future与promise实现异步任务链式调用执行逻辑》有用,将其分享出去将是对创作者最好的鼓励。

在C++的异步编程体系中,std::promise用于在一个线程中设置异步操作的结果,std::future则用于在另一个线程中获取这个结果,二者配合可以实现跨线程的结果传递。要实现异步任务的链式调用,核心思路就是让前一个任务的结果作为后一个任务的输入,通过promise和future的衔接完成整个调用链。

C++如何用std::future与promise实现异步任务链式调用执行逻辑

核心组件基础概念

首先我们需要明确两个核心组件的基本用法:

  • std::promise:是一个承诺对象,我们可以在异步线程中调用它的set_value方法设置结果,也可以调用set_exception设置异常。
  • std::future:是未来对象,通过promise的get_future方法获取,调用它的get方法可以阻塞等待promise设置结果,获取之后才能继续执行后续逻辑。

链式调用的实现思路

任务链式调用的本质是前一个任务完成后,自动触发下一个任务的执行,并且前一个任务的结果要传递给下一个任务。我们可以通过封装任务执行逻辑,让每个任务内部持有下一个任务的promise,当前任务完成后将结果设置到下一个任务的promise中,从而触发下一个任务的future等待结束,执行后续逻辑。

基础链式调用实现

我们先实现一个简单的两个任务链式调用,第一个任务执行完成后,结果传递给第二个任务执行:

#include <iostream>
#include <future>
#include <thread>
#include <functional>

// 第一个异步任务,接收输入参数,返回计算结果
int task1(int input) {
    std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟耗时操作
    return input * 2;
}

// 第二个异步任务,接收第一个任务的结果,返回最终计算结果
int task2(int input) {
    std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟耗时操作
    return input + 10;
}

int main() {
    // 创建第一个任务的promise和future
    std::promise<int> promise1;
    std::future<int> future1 = promise1.get_future();

    // 启动第一个任务的线程
    std::thread t1([&promise1]() {
        int result = task1(5); // 执行第一个任务,输入参数为5
        promise1.set_value(result); // 将结果设置到promise1中
    });

    // 创建第二个任务的promise和future
    std::promise<int> promise2;
    std::future<int> future2 = promise2.get_future();

    // 启动第二个任务的线程,等待第一个任务的结果
    std::thread t2([&promise2, &future1]() {
        int pre_result = future1.get(); // 阻塞等待第一个任务的结果
        int result = task2(pre_result); // 用第一个任务的结果执行第二个任务
        promise2.set_value(result); // 将第二个任务的结果设置到promise2中
    });

    // 获取最终链式调用的结果
    int final_result = future2.get();
    std::cout << "链式调用最终结果: " << final_result << std::endl;

    t1.join();
    t2.join();
    return 0;
}

通用链式调用封装

上面的实现只能固定两个任务,我们可以封装一个通用的链式调用工具,支持任意多个任务按顺序执行:

#include <iostream>
#include <future>
#include <thread>
#include <vector>
#include <functional>
#include <memory>

// 链式调用管理器
class AsyncTaskChain {
public:
    // 添加任务到链中,任务类型为接收上一个结果返回新结果的函数
    template <typename Func>
    void then(Func&& func) {
        tasks.emplace_back(std::forward<Func>(func));
    }

    // 启动链式调用,传入初始参数
    template <typename T>
    std::future<T> execute(T init_val) {
        // 创建最终结果的promise
        auto final_promise = std::make_shared<std::promise<T>>();
        std::future<T> final_future = final_promise->get_future();

        // 如果没有任务,直接返回初始值
        if (tasks.empty()) {
            final_promise->set_value(init_val);
            return final_future;
        }

        // 反向遍历任务,从最后一个任务开始创建promise和future链
        std::shared_ptr<std::promise<T>> prev_promise = final_promise;
        for (int i = tasks.size() - 1; i >= 0; --i) {
            auto current_promise = std::make_shared<std::promise<T>>();
            std::future<T> current_future = current_promise->get_future();
            auto task_func = tasks[i];

            // 启动线程执行当前任务,等待上一个任务的结果
            std::thread([current_promise, prev_promise, task_func, current_future]() mutable {
                // 如果是最后一个任务,等待初始值或者前一个任务的结果
                T input;
                if (prev_promise->get_future().valid()) {
                    input = prev_promise->get_future().get();
                }
                T result = task_func(input);
                current_promise->set_value(result);
            }).detach();

            prev_promise = current_promise;
        }

        // 设置初始值到第一个任务的promise
        prev_promise->set_value(init_val);

        return final_future;
    }

private:
    std::vector<std::function<int(int)>> tasks; // 任务列表,这里简化为统一接收int返回int
};

// 示例任务函数
int add_ten(int val) {
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    return val + 10;
}

int multiply_two(int val) {
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    return val * 2;
}

int subtract_five(int val) {
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    return val - 5;
}

int main() {
    AsyncTaskChain chain;
    // 添加三个任务到链中
    chain.then(add_ten);
    chain.then(multiply_two);
    chain.then(subtract_five);

    // 执行链式调用,初始值为3
    std::future<int> result_future = chain.execute(3);
    int final_result = result_future.get();
    std::cout << "通用链式调用最终结果: " << final_result << std::endl;
    // 执行逻辑:3+10=13,13*2=26,26-5=21,最终输出21
    return 0;
}

注意事项

  • 使用std::future的get方法时,只能调用一次,多次调用会导致未定义行为,如果需要多次获取结果,可以改用std::shared_future。
  • 如果promise在销毁前没有设置值,调用future的get方法会抛出std::future_error异常,所以需要确保每个promise都有对应的结果设置逻辑。
  • 链式调用中如果某个任务抛出异常,需要在promise中调用set_exception方法设置异常,否则后续任务会一直阻塞等待结果。
  • 线程的创建和销毁有一定开销,如果任务链较长,可以考虑使用线程池来优化性能,避免频繁创建线程。

总结

通过std::future和std::promise的配合,我们可以实现灵活的异步任务链式调用逻辑,核心是利用promise设置结果、future等待结果的机制,将多个异步任务的结果传递串联起来。上述通用封装可以满足大部分简单的链式调用需求,实际开发中可以根据业务场景调整任务函数的参数和返回值类型,适配更复杂的业务逻辑。

C++std::futurestd::promise异步任务任务链式调用修改时间:2026-07-19 13:48:39

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。