std::async和std::future异步编程

基本概念

异步操作:指的是不会立即完成,而是会在将来的某个时间点完成的操作。在 C++ 中,异步操作可以通过多种方式实现,比如使用 std::async、std::thread 配合 std::promise/std::future,或者第三方库如 Boost.Asio。

一、std::future

std::future:是一个模板类,用于表示异步操作的结果。可以通过 std::future 的成员函数来查询异步操作是否完成,等待异步操作完成,并获取其结果。

常用函数:

1. get()

功能:阻塞当前线程,直到与 std::future对象关联的异步操作完成,并返回异步操作的结果。如果异步操作抛出了异常,get() 会重新抛出该异常。

注意:get()方法只能被调用一次。调用后,std::future 对象将变为无效状态。

2. wait()

功能:阻塞当前线程,直到与std::future 对象关联的异步操作完成。它不返回任何结果,也不抛出异步操作中发生的异常(如果有的话)

3. wait_for(duration)

功能:尝试阻塞当前线程,直到与 std::future对象关联的异步操作完成或指定的时间间隔过去。

  • 如果异步操作在指定时间内完成,则返回std::future_status::ready;
  • 如果时间间隔过去但异步操作尚未完成,则返回std::future_status::timeout;
  • 如果 std::future对象关联的共享状态已经无效(例如,由于调用了get()),则返回std::future_status::deferred_no_state。 参数:duration是一个时间段,指定等待的最大时间。
4. wait_until(time_point)

功能:与 wait_for类似,但它是基于绝对时间点而不是时间段来等待。

  • 如果异步操作在指定的时间点之前完成,则返回std::future_status::ready;
  • 如果时间点到达但异步操作尚未完成,则返回std::future_status::timeout;
  • 如果 std::future对象关联的共享状态已经无效,则返回std::future_status::deferred_no_state。参数:time_point是一个时间点,指定等待的截止时间。
5. valid()

功能:检查 std::future 对象是否关联了一个有效的共享状态。
如果std::future 对象是由默认构造函数创建的,或者其共享状态已经被 get() 或 wait() 消耗,则返回 false;否则返回 true。

6. share()

功能:将 std::future 对象的共享状态转移到一个新的std::shared_future 对象中。这使得多个 std::shared_future 对象可以引用同一个异步操作的结果。
调用share() 后,原 std::future 对象将不再有效(即 valid() 返回 false)。

二、std::async

std::async 是 C++11 引入的一个函数模板,它提供了一种启动异步任务的方式。当你需要并行地执行某些操作,但又不想直接管理线程(例如,通过 std::thread)时,std::async 是一个很好的选择。它允许你以非常简洁的方式启动一个异步任务,并通过返回的 std::future 对象来查询任务的状态和获取其结果。

函数原型

template<class Fn, class... Args>  
future<typename std::result_of<Fn(Args...)>::type> async(std::launch policy, Fn&& fn, Args&&... args);
  • Fn:可调用对象的类型,比如函数、lambda表达式、函数对象等。
  • Args…:传递给可调用对象的参数类型列表。
  • std::launch policy:一个启动策略,用于指示std::async 如何执行任务。常用的启动策略包括std::launch::async(尽可能异步地执行任务)和std::launch::deferred(延迟执行,直到调用future::get 或future::wait)。注意,从C++17开始,启动策略的参数是可选的,且不再推荐显式指定(因为编译器可以优化选择)。
  • 返回类型:一个std::future 对象,该对象与异步操作的结果相关联。std::future 的模板参数是可调用对象返回类型的推导。

代码示例:

#include <iostream>  
#include <future>  
  
// 假设的 do_some_work 函数,它接受两个整数参数并返回它们的和  
int do_some_work(int x, int y) {  
    // 这里不实际进行任何耗时操作,只是为了演示  
    return x + y;  
}  
  
int main() {  
    // 使用 std::async 异步执行 do_some_work,并传递两个参数
    //std::future<int> result = std::async(std::launch::async, do_some_work, 3, 4);  
    auto result = std::async(std::launch::async, do_some_work, 3, 4);  
  
    // 在这里可以执行其他任务,而不会阻塞等待 do_some_work 完成  
  
    // 等待异步任务完成并获取结果  
    std::cout << "The result is " << result.get() << std::endl; // 输出: The result is 7  
  
    return 0;  
}

相关推荐

  1. C# - 异步编程同步编程总结

    2024-07-15 04:06:01       25 阅读
  2. Rust基础拾遗--并发异步编程

    2024-07-15 04:06:01       45 阅读
  3. Flutter-----异步编程:FutureStream

    2024-07-15 04:06:01       31 阅读
  4. std::asyncstd::future异步编程

    2024-07-15 04:06:01       23 阅读
  5. flask 异步编程 asyncio

    2024-07-15 04:06:01       55 阅读
  6. SpringBoot 异步编程

    2024-07-15 04:06:01       46 阅读
  7. c#异步编程

    2024-07-15 04:06:01       42 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-15 04:06:01       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-15 04:06:01       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-15 04:06:01       57 阅读
  4. Python语言-面向对象

    2024-07-15 04:06:01       68 阅读

热门阅读

  1. C++智能指针

    2024-07-15 04:06:01       19 阅读
  2. Python面试题:如何在 Python 中进行单元测试?

    2024-07-15 04:06:01       24 阅读
  3. git使用

    2024-07-15 04:06:01       20 阅读
  4. 哪个外汇平台可以交易美股?

    2024-07-15 04:06:01       19 阅读
  5. ubuntu disk

    2024-07-15 04:06:01       15 阅读
  6. 数据结构与算法基础篇--递归

    2024-07-15 04:06:01       20 阅读
  7. 来看一个14台480KW的充电站实际收入情况

    2024-07-15 04:06:01       19 阅读
  8. dify/api/models/workflow.py文件中的数据表

    2024-07-15 04:06:01       21 阅读
  9. Linux 命令集

    2024-07-15 04:06:01       23 阅读
  10. 代码随想录算法训练营第34天

    2024-07-15 04:06:01       25 阅读