当前位置: 首页 > news >正文

【C++】C++异步编程四剑客:future、async、promise和packaged_task详解

C++异步编程四剑客:future、async、promise和packaged_task详解

1. 引言

1.1 异步编程的重要性

在现代C++编程中,异步操作是提高程序性能和响应能力的关键技术。它允许程序在等待耗时操作(如I/O、网络请求或复杂计算)完成时继续执行其他任务,从而充分利用系统资源。

1.2 C++中的异步工具

C++11引入了强大的异步编程支持,主要包括四个核心组件:

  • std::future/std::shared_future:异步结果获取机制
  • std::async:简单的异步任务启动器
  • std::promise:异步结果提供者
  • std::packaged_task:可调用对象的包装器

2. std::future:异步结果的桥梁

2.1 基本概念

std::future是一个模板类,它提供了一种访问异步操作结果的机制。一个future对象通常与某个异步操作相关联,并可以在未来某个时刻获取该操作的结果。

2.2 主要功能

  • get():获取异步操作的结果(如果结果未就绪,会阻塞当前线程)
  • wait():等待异步操作完成
  • wait_for()/wait_until():带超时的等待

2.3 使用示例

#include <iostream>
#include <future>
#include <thread>int compute() {std::this_thread::sleep_for(std::chrono::seconds(2));return 42;
}int main() {std::future<int> result = std::async(std::launch::async, compute);std::cout << "Waiting for result..." << std::endl;std::cout << "Result: " << result.get() << std::endl;return 0;
}

3. std::async:简单的异步任务启动器

3.1 基本用法

std::async是启动异步任务的最简单方式,它返回一个std::future对象,通过该对象可以获取异步任务的结果。

3.2 启动策略

  • std::launch::async:强制在新线程中执行
  • std::launch::deferred:延迟执行,直到调用future.get()future.wait()
  • 默认策略:由实现决定

3.3 注意事项

  • 返回值std::future析构时会隐式等待
  • 不适合需要精细控制线程的场景

3.4 示例代码

auto future1 = std::async(std::launch::async, []{// 耗时计算return calculateSomething();
});auto future2 = std::async(std::launch::deferred, []{// 这个任务不会立即执行return calculateSomethingElse();
});// 只有调用get()时才会执行future2的任务
auto result = future1.get() + future2.get();

4. std::promise:手动设置异步结果

4.1 核心概念

std::promise允许显式地设置一个值或异常,这个值可以通过关联的std::future对象获取。

4.2 典型使用场景

  • 需要手动控制结果设置的时机
  • 跨线程回调
  • 复杂异步流程控制

4.3 基本用法

#include <iostream>
#include <future>
#include <thread>void compute(std::promise<int> prom) {try {int result = 42; // 模拟计算prom.set_value(result);} catch(...) {prom.set_exception(std::current_exception());}
}int main() {std::promise<int> prom;std::future<int> fut = prom.get_future();std::thread t(compute, std::move(prom));t.detach();std::cout << "Result: " << fut.get() << std::endl;return 0;
}

5. std::packaged_task:可调用对象的包装器

5.1 基本概念

std::packaged_task包装一个可调用对象(函数、lambda表达式、函数对象等),并允许异步获取该调用的结果。

5.2 主要特点

  • 将任务与结果获取分离
  • 可以像普通函数对象一样被调用
  • 适合需要将任务传递给线程池的场景

5.3 使用示例

#include <iostream>
#include <future>
#include <thread>
#include <deque>std::deque<std::packaged_task<int()>> task_queue;void worker_thread() {while (!task_queue.empty()) {auto task = std::move(task_queue.front());task_queue.pop_front();task(); // 执行任务}
}int main() {std::packaged_task<int()> task([]{return 42;});std::future<int> result = task.get_future();task_queue.push_back(std::move(task));std::thread t(worker_thread);t.join();std::cout << "Result: " << result.get() << std::endl;return 0;
}

6. 四者的比较与选择指南

6.1 功能对比

工具适用场景线程管理灵活性
std::async简单异步任务自动
std::promise需要手动设置结果的复杂场景手动
std::packaged_task需要传递任务对象的场景手动

6.2 选择建议

  1. 优先考虑std::async:适用于简单的异步任务
  2. 需要精细控制时使用std::promise
  3. 需要将任务对象传递给线程池时使用std::packaged_task

7. 高级主题与最佳实践

7.1 异常处理

  • 使用promise.set_exception()传递异常
  • future.get()时捕获异常

7.2 超时控制

auto status = future.wait_for(std::chrono::seconds(1));
if (status == std::future_status::ready) {// 任务已完成
} else {// 超时处理
}

7.3 共享结果

使用std::shared_future实现多线程共享异步结果:

std::promise<int> prom;
std::shared_future<int> shared_fut = prom.get_future().share();// 多个线程可以同时访问shared_fut

8. 总结

C++的异步编程工具提供了不同层次的抽象,从简单的std::async到更灵活的std::promisestd::packaged_task,开发者可以根据具体需求选择合适的工具。理解这些工具的特性和适用场景,能够帮助我们编写出更高效、更健壮的并发程序。

相关文章:

  • 使用 CodeBuddy 实现视频合并工具:解决本地视频处理痛点
  • 可增添功能的鼠标右键优化工具
  • LumaDot (亮度可调的屏幕圆点)
  • 【Linux仓库】权限的量子纠缠:用户/组/other如何编织Linux访问控制网?
  • uniapp+ts 多环境编译
  • WebSockets 在实时通信中的应用与优化
  • H3C-W2000-G2【透明反代理】
  • 【Linux网络篇】:Socket网络套接字以及简单的UDP网络程序编写
  • 【如何做好一份技术文档?】用Javadoc与PlantUML构建高质量技术文档(API文档自动化部署)
  • 贪心介绍 LeetCode 455.分发饼干 LeetCode 376. 摆动序列 LeetCode 53. 最大子序和
  • 力扣热题100之排序链表
  • leetcode - 前缀和
  • 前端框架token相关bug,前后端本地联调
  • 每日算法刷题Day14 5.24:leetcode不定长滑动窗口求子数组个数越长越合法4道题,用时1h20min
  • 【MySQL】07.表内容的操作
  • leetcode438.找到字符串中所有字母异位词
  • 电脑C盘清理技巧:释放空间,提升性能
  • 微信小程序调试
  • 前端大文件上传性能优化实战:分片上传分析与实战
  • JVM 的垃圾回收机制 GC
  • 网站做ppt模板/什么叫做关键词
  • 宝鸡外贸网站建设/seo排名赚app
  • 公众号引流推广吸粉方案/北京网站优化策略
  • 做市场调查的网站免费/福州关键词排名优化
  • 淘宝网站优化实例/网络电商推广方案
  • 一个主机可以建设多少个网站/网站流量统计查询