C++ 异步编程:std::async、std::future、std::packaged_task 和 std::prom ...

打印 上一主题 下一主题

主题 1014|帖子 1014|积分 3042

C++ 异步编程:std::async、std::future、std::packaged_task 和 std::promise

在当代 C++ 编程中,异步编程已经成为一种常见的模式。利用 C++11 引入的尺度库组件 std::async、std::future、std::packaged_task 和 std::promise,我们可以更方便地处理多线程使命。本文将先容这些组件的基本用法及其应用场景,帮助你理解如何利用这些工具实现高效的异步编程。

1. std::future 和 std::promise

std::future

std::future 是一种用于获取异步盘算结果的机制。它提供了一个等待异步使命完成并获取结果的方法。std::future 对象通过与 std::promise 结合使用,允许线程安全地获取异步利用的结果或异常。
基本用法:
  1. #include <iostream>
  2. #include <thread>
  3. #include <future>
  4. void async_task(std::promise<int>& prom) {
  5.     std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作
  6.     prom.set_value(42); // 设置计算结果
  7. }
  8. int main() {
  9.     std::promise<int> prom;
  10.     std::future<int> fut = prom.get_future();
  11.     std::thread t(async_task, std::ref(prom)); // 使用 std::ref 传递 promise 的引用
  12.     t.detach(); // 线程分离,允许在主线程中继续执行
  13.     int result = fut.get(); // 等待异步任务完成并获取结果
  14.     std::cout << "Result: " << result << std::endl;
  15.     return 0;
  16. }
复制代码
表明:


  • std::promise<int> 创建一个 promise 对象,用于设置值。
  • std::future<int> fut = prom.get_future(); 从 promise 获取 future 对象。
  • 在异步线程中,调用 prom.set_value(42); 设置结果。
  • fut.get(); 阻塞当前线程,直到结果可用。
std::promise

std::promise 用于在异步利用中设置结果。它与 std::future 结合使用,以便从线程中转达结果或异常。std::promise 对象只能被设置一次,设置多次会引发异常。
基本用法:
  1. #include <iostream>
  2. #include <thread>
  3. #include <future>
  4. void async_task(std::promise<int> prom) {
  5.     prom.set_value(42); // 设置计算结果
  6. }
  7. int main() {
  8.     std::promise<int> prom;
  9.     std::future<int> fut = prom.get_future();
  10.     std::thread t(async_task, std::move(prom)); // 使用 std::move 转移 promise
  11.     t.join(); // 等待线程完成
  12.     int result = fut.get(); // 获取异步任务的结果(会阻塞直到结果可用)
  13.     std::cout << "Result: " << result << std::endl;
  14.     return 0;
  15. }
复制代码
表明:


  • std::promise<int> prom; 创建 promise 对象。
  • std::future<int> fut = prom.get_future(); 获取 future 对象。
  • 在异步线程中,通过 prom.set_value(42); 设置结果。
  • fut.get(); 获取结果并阻塞当前线程。
2. std::packaged_task

std::packaged_task 是一个可调用对象,用于将使命的结果与 std::future 绑定。它允许你将一个普通的函数或函数对象封装为一个异步使命,并从中获取结果。
基本用法:
  1. #include <iostream>
  2. #include <thread>
  3. #include <future>
  4. int long_computation(int x) {
  5.     std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作
  6.     return x * x;
  7. }
  8. int main() {
  9.     std::packaged_task<int(int)> task(long_computation); // 创建任务
  10.     std::future<int> fut = task.get_future(); // 获取 future 对象
  11.     std::thread t(std::move(task), 10); // 使用 std::move 转移任务,并传递参数
  12.     t.join(); // 等待线程完成
  13.     int result = fut.get(); // 获取异步任务的结果(会阻塞直到结果可用)
  14.     std::cout << "Result: " << result << std::endl;
  15.     return 0;
  16. }
复制代码
表明:


  • std::packaged_task<int(int)> task(long_computation); 创建一个使命对象,封装 long_computation 函数。
  • std::future<int> fut = task.get_future(); 获取与使命关联的 future 对象。
  • std::thread t(std::move(task), 10); 将使命移动到线程中,并转达参数。
  • fut.get(); 获取使命结果。
3. std::async

std::async 是一种更高条理的异步利用工具,它可以在后台线程中异步实行函数,并返回一个 std::future 对象,用于获取结果。它比手动创建线程更简单。
基本用法:
  1. #include <iostream>
  2. #include <future>
  3. #include <chrono>
  4. int long_computation(int x) {
  5.     std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作
  6.     return x * x;
  7. }
  8. int main() {
  9.     std::future<int> fut = std::async(std::launch::async, long_computation, 10); // 异步执行
  10.     // 可以在这里做其他事情
  11.     std::cout << "Doing other things while waiting for the result..." << std::endl;
  12.     int result = fut.get(); // 获取异步任务的结果(会阻塞直到结果可用)
  13.     std::cout << "Result: " << result << std::endl;
  14.     return 0;
  15. }
复制代码
表明:


  • std::async(std::launch::async, long_computation, 10); 异步实行 long_computation 函数,并转达参数。
  • fut.get(); 获取结果并阻塞当前线程,直到结果可用。
总结



  • std::promise 用于设置异步利用的结果或异常。
  • std::future 用于获取异步利用的结果或异常。
  • std::packaged_task 封装函数为使命,并与 std::future 结合使用。
  • std::async 简化异步使命的创建和管理,自动处理线程和使命。
通过理解和使用这些 C++ 尺度库组件,你可以更高效地进行异步编程,管理复杂的使命和线程利用。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

老婆出轨

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表