C++11中std::future的使用详解和实战示例

在 C++11 中,std::future 是标准库中的一个强大工具,用于实现异步任务获取返回值。它与 std::asyncstd::promise 搭配使用,能够从并发任务中安全获取结果,是线程通信和异步执行的核心组件之一。


一、std::future 是什么?

  • 它表示一个异步操作的结果,用于获取尚未完成任务的值。
  • 通常与 std::asyncstd::promise 搭配使用。
  • std::future<T>:未来某个时间点将拥有一个类型为 T 的结果。

二、典型使用场景

场景一:std::async + std::future(最常见,简单)

异步执行一个函数,主线程稍后使用 future.get() 获取其结果。

场景二:std::promise + std::future(手动控制结果传递)

适用于线程中产生结果、异常或信号时主动传递给主线程。


三、基础示例(使用 std::async

#include <iostream>
#include <future>
#include <chrono>

// 一个耗时函数
int slow_add(int a, int b) {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    return a + b;
}

int main() {
    std::cout << "Starting async task...\n";

    // 启动异步任务,立即返回 std::future 对象
    std::future<int> result = std::async(std::launch::async, slow_add, 3, 4);

    std::cout << "Doing other work...\n";

    // 等待结果并获取(阻塞)
    int value = result.get();

    std::cout << "Result: " << value << std::endl;
    return 0;
}

输出:

Starting async task...
Doing other work...
Result: 7

四、控制异步启动策略

std::future<int> f1 = std::async(std::launch::async, func);   // 异步立即启动线程
std::future<int> f2 = std::async(std::launch::deferred, func); // 延迟执行(在 get() 时运行)
std::future<int> f3 = std::async(std::launch::async | std::launch::deferred, func); // 默认行为

五、std::promise 搭配 std::future

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

void calculate(std::promise<int> p) {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    p.set_value(42);  // 设置结果
}

int main() {
    std::promise<int> prom;
    std::future<int> fut = prom.get_future();  // 获取 future

    std::thread t(calculate, std::move(prom));  // 线程中设置值

    std::cout << "Waiting for result..." << std::endl;
    int result = fut.get();  // 阻塞等待结果

    std::cout << "Result: " << result << std::endl;
    t.join();
    return 0;
}

六、常用函数说明

函数名功能说明
future.get()获取结果,阻塞直到就绪(只能调用一次)
future.wait()阻塞直到任务完成
future.wait_for(dur)超时等待
future.wait_until(tp)等待到指定时间点
future.valid()判断是否持有共享状态

七、注意事项

  • std::future::get() 只能调用一次,之后对象就失效(invalid)。
  • async 的函数抛出异常,该异常会被捕获,并在 get() 时重新抛出。
  • std::future 不是线程安全的:多个线程不能同时访问同一个 future

八、进阶示例:多个任务并发执行并获取结果

#include <iostream>
#include <vector>
#include <future>

int work(int id) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100 * id));
    return id * id;
}

int main() {
    std::vector<std::future<int>> results;

    for (int i = 1; i <= 5; ++i) {
        results.push_back(std::async(std::launch::async, work, i));
    }

    for (auto& fut : results) {
        std::cout << "Result: " << fut.get() << std::endl;
    }

    return 0;
}

九、数据预处理并行化综合示例

应用场景示例:点云数据批量预处理(并发执行)

假设有大量点云块(或图像帧)需要执行滤波、去噪、下采样等操作,顺序执行较慢。可以使用 std::async 启动多个线程并行处理每个数据块。


示例代码:点云块并行处理

#include <iostream>
#include <vector>
#include <future>
#include <random>
#include <chrono>

// 假设每个点云块是一个 vector<float>
using PointCloudBlock = std::vector<float>;

// 模拟预处理函数(如滤波、下采样等)
PointCloudBlock preprocessBlock(const PointCloudBlock& input, int blockId) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟耗时
    PointCloudBlock result = input;
    for (auto& p : result) {
        p *= 0.9f; // 模拟处理
    }
    std::cout << "Block " << blockId << " processed\n";
    return result;
}

int main() {
    const int blockCount = 8;

    // 模拟 8 个点云块
    std::vector<PointCloudBlock> inputBlocks(blockCount, PointCloudBlock(1000, 1.0f));

    std::vector<std::future<PointCloudBlock>> futures;

    // 并发预处理每个块
    for (int i = 0; i < blockCount; ++i) {
        futures.push_back(std::async(std::launch::async, preprocessBlock, inputBlocks[i], i));
    }

    // 收集结果
    std::vector<PointCloudBlock> processedBlocks;
    for (auto& fut : futures) {
        processedBlocks.push_back(fut.get());
    }

    std::cout << "All blocks processed.\n";
    return 0;
}

多线程处理的好处

优点说明
提高吞吐并发预处理多个任务,CPU 多核资源充分利用
无需额外线程池使用 std::async 自动调度线程
支持异常处理若某个任务异常,future.get() 时可捕获
易于封装可以包装为模块,适用于图像/点云/文本等任意数据

十、小结:何时用 future

  • 想让线程返回值给主线程。
  • 延迟执行某个任务。
  • 需要对异步任务的结果、超时、异常处理
  • 实现任务通信(如 promise 设置结果、主线程读取)。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云SLAM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值