首页 > 其他分享 >future

future

时间:2024-03-25 18:46:52浏览次数:27  
标签:std get future shared 共享 wait

C++11 提供了std::future类模板,future 对象提供访问异步操作结果的机制,很轻松解决从异步任务中返回结果。

在 C++ 标准库中,有两种“期望”,使用两种类型模板实现(这里主要介绍的是唯一期望):

  • 唯一期望(unique futuresstd::future<>) 实例只能与一个指定事件相关联。
  • 共享期望(shared futuresstd::shared_future<>) 实例能关联多个事件。

事实上,一个std::future对象在内部存储一个将来会被某个 provider 赋值的值,并提供了一个访问该值的机制,通过get()成员函数实现。但如果有人试图在get()函数可用之前通过它来访问相关的值,那么get()函数将会阻塞,直到该值可用。

一个有效的std::future对象通常由以下三种 Provider 创建,并和某个共享状态相关联。Provider 可以是函数或者类,他们分别是:

  • std::async函数;
  • std::promise::get_future,get_future 为 promise 类的成员函数;
  • std::packaged_task::get_future,此时 get_future为 packaged_task 的成员函数;

C++11 提供的 <future> 头文件中包含了以下几个类和函数:

  • Providers 类:std::promise, std::package_task
  • Futures 类:std::future, shared_future
  • Providers 函数:std::async()
  • 其他类型:std::future_error, std::future_errc, std::future_status, std::launch

std::future构造函数

std::future一般由上面三种 Provider 创建,不过也提供了构造函数

// default 由 std::future 默认构造函数创建的 future 对象不是有效的
future() noexcept;
// copy [deleted] 
future (const future&) = delete;
// move
future (future&& x) noexcept;

不过std::future的拷贝构造函数是被禁用的,只提供了默认的构造函数和 move 构造函数。另外,std::future的普通赋值操作也被禁用,只提供了 move 赋值操作。如下代码所示:

std::future<int> fut;           // 默认构造函数
fut = std::async(do_some_task);   // move-赋值操作。

future 作为线程间一种同步手段,还有一个知识就是其共享状态。所谓共享状态就是这个 future 对象所表示的异步操作是否能够在其他线程中被访问。一般来说,通过异步操作创建的 future 会被这些异步操作设置共享状态future 对象可以通过 valid() 函数查询其共享状态是否有效 ,一般来说,只有当 valid() 返回 true的时候才调用 get() 去获取结果

std::future::share()

返回一个 std::shared_future 对象,调用该函数之后,该 std::future 对象本身已经不和任何共享状态相关联,因此该 std::future 的状态不再是 valid 的了。

std::shared_future<T> share() noexcept;
#include <iostream>       // std::cout
#include <future>         // std::async, std::future, std::shared_future

int do_get_value() { return 10; }

int main ()
{
    std::future<int> fut = std::async(do_get_value);
    std::shared_future<int> shared_fut = fut.share();

    // 共享的 future 对象可以被多次访问.
    std::cout << "value: " << shared_fut.get() << '\n';
    std::cout << "its double: " << shared_fut.get()*2 << '\n';

    return 0;
}

std::future::get()

std::future::get 一共有三种形式:

T get(); // (仅为泛型 future 模板的成员)
T& get(); // (仅为 future<T&> 模板特化的成员)
void get(); // (仅为 future<void> 模板特化的成员)

当与该 std::future 对象相关联的共享状态标志变为 ready 后,调用该函数将返回保存在共享状态中的值,如果共享状态的标志不为 ready,则调用该函数会阻塞当前的调用者,而此后一旦共享状态的标志变为 ready,get 返回 Provider 所设置的共享状态的值或者异常(如果抛出了异常)。

std::future::valid()

bool valid() const noexcept;

检查当前的 std::future 对象是否有效,即释放与某个共享状态相关联。一个有效的 std::future 对象只能通过 std::async(), std::future::get_future 或者 std::packaged_task::get_future 来初始化。另外由 std::future 默认构造函数创建的 std::future 对象是无效(invalid)的,当然通过 std::future 的 move 赋值后该 std::future 对象也可以变为 valid。

std::future::wait()

等待与当前std::future 对象相关联的共享状态的标志变为 ready。

如果共享状态的标志不是 ready,调用该函数会被阻塞当前线程,直到共享状态的标志变为 ready。一旦共享状态的标志变为 ready,wait() 函数返回,当前线程被解除阻塞,但是 wait() 并不读取共享状态的值或者异常。

std::future::wait_for()

与 std::future::wait() 的功能类似,即等待与该 std::future 对象相关联的共享状态的标志变为 ready,该函数原型如下:

template< class Rep, class Period >
    std::future_status wait_for( const std::chrono::duration<Rep,Period>& timeout_duration ) const;

而与 std::future::wait() 不同的是,wait_for() 可以设置一个时间段 rel_time,如果共享状态的标志在该时间段结束之前没有被 Provider 设置为 ready,则调用 wait_for 的线程被阻塞,在等待了 timeout_duration 的时间长度后 wait_until() 返回,返回值如下:

future status::ready 共享状态的标志已经变为 ready,即 Provider 在共享状态上设置了值或者异常。
future status::timeout 超时,即在规定的时间内共享状态的标志没有变为 ready。
future status::deferred 共享状态包含一个 deferred 函数。

std::future::wait_until()

与 std::future::wait() 的功能类似,即等待与该 std::future 对象相关联的共享状态的标志变为 ready,该函数原型如下:

template< class Clock, class Duration >
    std::future_status wait_until( const std::chrono::time_point<Clock,Duration>& timeout_time ) const;

而 与 std::future::wait() 不同的是,wait_until() 可以设置一个系统绝对时间点 abs_time,如果共享状态的标志在该时间点到来之前没有被 Provider 设置为 ready,则调用 wait_until 的线程被阻塞,在 abs_time 这一时刻到来之后 wait_for() 返回,返回值如下:

future status::ready 共享状态的标志已经变为 ready,即 Provider 在共享状态上设置了值或者异常。
future status::timeout 超时,即在规定的时间内共享状态的标志没有变为 ready。
future status::deferred 共享状态包含一个 deferred 函数。

std::shared_future

std::shared_future 共有四种构造函数,如下所示:

shared_future() noexcept; // default
shared_future (const shared_future& x); // copy
shared_future (shared_future&& x) noexcept; // move
shared_future (future<T>&& x) noexcept; // move from future
 

std::shared_future 与 std::future 类似,但是 std::shared_future 可以拷贝、多个 std::shared_future 可以共享某个共享状态的最终结果(即共享状态的某个值或者异常)。shared_future 可以通过某个 std::future 对象隐式转换,或者通过 std::future::share() 显示转换,无论哪种转换,被转换的那个 std::future 对象都会变为 not-valid。

标签:std,get,future,shared,共享,wait
From: https://www.cnblogs.com/love-9/p/18095047

相关文章

  • CompletableFuture概述、创建方式、常用API、电商比价需求
    ①.CompletableFuture概述②.CompletableFuture创建方式③.CompletableFutureAPI①.获得结果和触发计算(get、getNow、join、complete)②.对计算结果进行处理(thenApply、handle)③.对计算结果进行消费(thenRun、thenAccept、thenApply)④.对计算速度进行选用(appl......
  • 中考英语首字母快速突破014-2021上海徐汇英语二模-Future Changes: Predictions and P
    PDF格式公众号回复关键字:ZKSZM014原文​Readthecommentsaboutchangesinthefuture.Howmuchdoyouagreewiththem?​Thedays,somepeopleworkathomeoneortwodaysaweekinsteadofgoingtoanofficeeveryday.Ithinkinthefuture......
  • std::promise返回的是future对象
    在C++中,std::promise对象调用get_future()方法返回一个std::future对象,而不是指针、引用或其他类型的对象。std::future对象用于获取与std::promise对象相关联的异步操作的结果。std::promise和std::future是C++标准库中的一部分,用于处理异步操作的结果。std::promise对象可以在......
  • 多线程系列(二十) -CompletableFuture使用详解
    一、摘要在上篇文章中,我们介绍了Future相关的用法,使用它可以获取异步任务执行的返回值。我们再次回顾一下Future相关的用法。publicclassFutureTest{publicstaticvoidmain(String[]args)throwsException{longstartTime=System.currentTimeMillis()......
  • 多线程系列(十九) -Future使用详解
    一、摘要在前几篇线程系列文章中,我们介绍了线程池的相关技术,任务执行类只需要实现Runnable接口,然后交给线程池,就可以轻松的实现异步执行多个任务的目标,提升程序的执行效率,比如如下异步执行任务下载。//创建一个线程池ExecutorServiceexecutor=Executors.newFixedThreadPool......
  • Java.CompletableFuture使用
    使用CompletableFuture替代Thread+Runnable解决Thread+Runnable没有返回值、串行化和组合任务问题1、CompletableFuture.runAsync异步没有返回值需要传入一个线程池publicstaticExecutorServiceexecutor=Executors.newFixedThreadPool(10);CompletableFuture.runAsync((......
  • CompletableFuture Demo
    CompletableFutureDemo题目:有一个数据库client,从数据库中取数据A和数据B,然后求和。请使用并发的知识,尽快的完成操作。/***{@code@author:}keboom*{@code@date:}2024/3/8*{@code@description:}*/publicclassDataBaseClient{@SneakyThrowspublic......
  • CompletableFuture使用说明
    前言创建线程的方式只有两种:继承Thread或者实现Runnable接口。但是这两种方法都存在一个缺陷,没有返回值Java1.5以后,可以通过向线程池提交一个Callable来获取一个包含返回值的Future对象Future接口的局限性当Future的线程进行了一个非常耗时的操作,那我们的主线程也就阻塞了......
  • Future和Callable
    Future和CallableRunnable缺陷不能返回一个返回值也不能抛出checkedExceptionCallable接口类似于Runnable,被其它线程执行的任务实现call方法有返回值Future可以用Future.get来获取Callable接口返回的执行结果,还可以通过Future.isDone()来判断任务是否已经执行完了,以及取消这个任......
  • JAVA之CompletableFuture
    目录CompletableFuture入门学习内容学习目标课程学习说明1、FuturevsCompletableFuture1.1准备工作1.2Future的局限性1.3CompletableFuture的优势2、创建异步任务2.1runAsync2.2supplyAsync2.3异步任务中的线程池2.4异步编程思想3、异步任务回调3.1thenApply3.2thenA......