`std::future`--异步的优势

news/2024/10/7 12:03:47

std::future 相比于直接使用线程在 C++ 中有几个重要的优势,主要体现在同步结果获取简化代码管理、以及更安全的异步任务管理等方面。以下是 std::future 的一些主要优势:

1. 自动结果获取与同步

  • std::future 提供了一种便捷的机制来获取异步任务的返回值。当我们使用线程时,通常无法轻松获得线程的返回值,线程函数如果有返回值,需要通过共享变量、全局变量或其他同步机制进行通信,这使得代码更加复杂。

  • 通过 std::future,可以轻松获取异步任务的结果,它在内部同步管理任务执行的结果。

    例子:

    #include <iostream>
    #include <future>int compute() {return 42;
    }int main() {std::future<int> result = std::async(std::launch::async, compute);std::cout << "Result: " << result.get() << std::endl; // 自动等待线程完成并返回结果return 0;
    }
    

    在这种情况下,result.get() 会等待线程完成,并获取异步任务的返回值 42。这比直接使用线程共享状态的方式要简单得多。

2. 简化代码管理

  • 使用 std::thread 需要手动管理线程的生命周期,比如使用 join() 来等待线程执行完成。而 std::future 通过 get() 或者 wait() 来等待任务完成,自动管理同步,不需要手动调用 join()

    直接使用线程时:

    #include <iostream>
    #include <thread>void compute(int &result) {result = 42;
    }int main() {int result;std::thread t(compute, std::ref(result));t.join(); // 必须手动调用 join() 等待线程完成std::cout << "Result: " << result << std::endl;return 0;
    }
    

    这里要通过 std::ref(result) 共享数据,并且必须手动管理线程的结束 (join()),否则程序会发生错误。

3. 更安全的异步任务管理

  • std::futurestd::async 可以更好地管理异步任务,避免直接操作线程带来的错误。比如,当线程没有被正确 join 时,程序可能崩溃,而 std::future 会自动等待异步任务完成。

  • 如果程序异常退出或者忘记调用 join()std::thread 会导致程序中断或者未定义行为。而 std::future 不会发生这些问题,它通过 get() 自动等待异步任务完成。

    例如,如果使用 std::thread,忘记 join(),程序会出现崩溃风险:

    std::thread t([] { std::this_thread::sleep_for(std::chrono::seconds(1)); });
    // 如果没有 t.join(),程序将崩溃
    

4. 异常管理

  • std::future 可以捕获异步任务中的异常,而直接使用线程时,异常管理需要额外的工作。在 std::future 中,get() 不仅可以获取任务的结果,还可以在任务中出现异常时,将该异常抛出,方便后续处理。

    例子:

    #include <iostream>
    #include <future>
    #include <stdexcept>int faulty_task() {throw std::runtime_error("Something went wrong!");
    }int main() {std::future<int> result = std::async(std::launch::async, faulty_task);try {int value = result.get(); // 在此捕获异常} catch (const std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;}return 0;
    }
    

    直接使用 std::thread 时,要处理任务中的异常需要复杂的机制,std::future 简化了这一过程。

5. 延迟启动任务

  • 使用 std::asyncstd::future,你可以选择是否立即启动线程,或者延迟执行任务(惰性启动)。通过 std::async 的第二个参数(如 std::launch::deferred),可以控制任务是否异步执行或延迟执行,这种灵活性在直接使用线程时无法轻易实现。

    惰性启动:

    std::future<int> result = std::async(std::launch::deferred, compute); // 任务并不会立即执行
    // result.get() 执行时,任务才开始执行
    

总结

std::future 的主要优势在于:

  • 简化了异步任务的结果获取与同步操作;
  • 提供了更好的异常管理;
  • 避免了手动管理线程生命周期的复杂性;
  • 提供了延迟执行(deferred execution)的灵活性。

相比之下,std::thread 直接操作线程,虽然可以让程序员显式控制任务,但在实际开发中,这种显式控制常常导致复杂的代码管理和更大的错误风险,因此 std::future 是一种更高层次、更安全的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/68594.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

张量矩阵乘法分块乘法概述

张量矩阵乘法分块乘法概述 介绍一下矩阵计算相关的内容, 从最基本的算法,到Cutlass这些线性代数模版库, 特别是Layout代数相关的内容,再逐渐细化到一些硬件实现访存优化和一些算子融合。 6.3.1 GEMM概述 1. GEMM定义 对于一个矩阵乘法, 定义如下: (6-1)一个矩阵乘法定义,如…

Java与线程

Java与线程 1. 线程的实现 线程是比进程更轻量级的调度执行单位,线程的引人,可以把一个进程的资源分配和执行调度分开,各个线程既可以共享进程资源(内存地址、文件IO等),又可以独立调度。目前线程是Java里面进行处理器资源调度的最基本单位。 主流的操作系统都提供了线程实…

矩阵分块乘法

矩阵分块乘法 通常可以把一个矩阵分成多个块, 例如, (6-4)可以将其划分为 4个块:(6-5) (6-6)分块后的矩阵记为:(6-7) 分块矩阵乘法如下所示:(6-7)划分不一定需要完全等间隔, 只需要满足子矩阵乘法规则即可, 如图6-27所示。图6-27 子矩阵划分不一定需要完全等间…

从硬件的视角看GEMM

从硬件的视角看GEMM 1. 分块乘法的内存层次架构 分块矩阵乘法,如图6-28所示, 通过将矩阵分块拆分,能够在处理器的Cache和寄存器内存放进行快速计算,计算完成后写回主存。图6-28 分块矩阵乘法 首先,所有的数据都在主内存中,如图6-29所示。图6-29 所有的数据都在主内存中 然…

电表行业强力推荐KY8023S6对标平替BL8023双向继电器驱动芯片

双向继电器驱动芯片KY8023S6对标平替BL8023。 产品特点 SOT23-6L和SOP-8 两种封装 静态功耗电流<1uA 输入高低转换电平为1.3V(Is=1A)左右,兼容多种单片机 工作电压5-40V,推荐工作电压5-30V 输入INA和INB端自带115k下拉电阻,一般可省略外围下拉电阻 集成高速续流二极管,…

重启后,idea 依赖爆红

没改动代码,但无法运行java项目 java: -source 1.5 中不支持……表达式/运算符java: 错误: 不支持发行版本 5解决:https://www.cnblogs.com/liu-han/p/16105953.html 文件→项目结构,SDK和项目/模块 语言级别的版本要一致SDK: 1.8 项目语言级别:SDK默认值 模块语言级别:SD…

[亲测]君临九州+单机安装教程+无需虚拟机+GM后台

今天给大家带来一款单机游戏的架设:君临九州,版本号:1.0.12.30。 另外:本人承接各种游戏架设(单机+联网) 本人为了学习和研究软件内含的设计思想和原理,带了架设教程仅供娱乐。 教程是本人亲自搭建成功的,绝对是完整可运行的,踩过的坑都给你们填上了。如果你是小白也没…

Leetcode 10. 正则表达式匹配

1.题目基本信息 1.1.题目描述 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。‘.’ 匹配任意单个字符 ‘*’ 匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分字符串。 1.2.题目地址 https://leetc…