C++11中std::shared_future的使用

2023-11-18

C++11中的std::shared_future是个模板类。std::future类似,std::shared_future提供了一种访问异步操作结果的机制;不同于std::future,std::shared_future允许多个线程等待同一个共享状态;不同于std::future仅支持移动操作,std::shared_future既支持移动操作也支持拷贝操作,而且多个shared_future对象可以引用相同的共享状态。std::shared_future还允许一旦共享状态就绪就可以多次检索共享状态下的值(A shared_future object behaves like a future object, except that it can be copied, and that more than one shared_future can share ownership over their end of a shared state. They also allow the value in the shared state to be retrieved multiple times once ready)。

std::shared_future对象可以通过std::future对象隐式转换,也可以通过显示调用std::future::share显示转换,在这两种情况下,原std::future对象都将变得无效。

共享状态(shared state)的生存期至少要持续到与之关联的最后一个对象被销毁为止。与std::future不同,通过shared_future::get检索的值不会释放共享对象的所有权。

std::future介绍参考:https://blog.csdn.net/fengbingchun/article/details/104115489

当你需要具有std::future的多个有效拷贝时会用到std::shared_future;或者多个使用者使用std::future时也会用到std::shared_future。

Consider std::future, std::shared_future to be like std::unique_ptr, std::shared_ptr.

模板类std::shared_future成员函数包括:

1. 构造函数:(1).不带参数的默认构造函数,此对象没有共享状态,因此它是无效的,但是它可以被赋予一个有效值;(2).拷贝构造:与const shared_future& x具有相同的共享状态,并与之共享所有权;(3).支持移动构造。

2. 析构函数:销毁shared_future对象,它是异常安全的。如果对象有效(即它可以访问共享状态),则将其与对象接触关联;如果它是与共享状态关联的唯一对象,则共享对象本身也将被销毁。

3. get函数:(1).当共享状态就绪时,返回存储在共享状态中的值的引用(或抛出异常)。(2).如果共享状态尚未就绪(即provider提供者尚未设置其值或异常),则该函数将阻塞调用的线程直到就绪。(3).当共享状态就绪后,则该函数将解除阻塞并返回(或抛出),但与future::get不同,不会释放其共享状态,允许其它shared_future对象也访问存储的值。(4).std::shared_future<void>::get()不返回任何值,但仍等待共享状态就绪才返回或抛出。

4. operator=:(1).拷贝赋值:该对象与const shared_future& rhs关联到相同的共享状态,并与之共享所有权;(2).移动赋值:该对象获取shared_future&& rhs的共享状态,rhs不再有效。

5. valid函数:检查共享状态的有效性,返回当前的shared_future对象是否与共享状态关联。

6. wait函数:(1).等待共享状态就绪。(2).如果共享状态尚未就绪(即提供者尚未设置其值或异常),则该函数将阻塞调用的线程直到就绪。(3).当共享状态就绪后,则该函数将解除阻塞并void返回。

7. wait_for函数:(1).等待共享状态在指定的时间内(time span)准备就绪。(2). 如果共享状态尚未就绪(即提供者尚未设置其值或异常),则该函数将阻塞调用的线程直到就绪或已达到设置的时间。(3).此函数的返回值类型为枚举类future_status。此枚举类有三种label:ready:共享状态已就绪;timeout:在指定的时间内未就绪;deferred:共享状态包含了一个延迟函数(deferred function)。(4).如果共享状态包含了一个延迟函数,则该函数不会阻塞,立即返回一个future_status::deferred值。

8. wait_until函数:(1). 等待共享状态在指定的时间点(time point)准备就绪。(2). 如果共享状态尚未就绪(即提供者尚未设置其值或异常),则该函数将阻塞调用的线程直到就绪或已达到指定的时间点。(3).此函数的返回值类型为枚举类future_status。(4).如果共享状态包含了一个延迟函数,则该函数不会阻塞,立即返回一个future_status::deferred值。

详细用法见下面的测试代码,下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "future.hpp"
#include <iostream>
#include <future>
#include <chrono>
#include <utility>
#include <thread>

namespace future_ {

///
// reference: https://en.cppreference.com/w/cpp/thread/shared_future
int test_shared_future_1()
{
	std::promise<void> ready_promise, t1_ready_promise, t2_ready_promise;
	// 通过std::future移动构造std::shared_future对象,t1_ready_promise和t2_ready_promise均会用到ready_future
	std::shared_future<void> ready_future(ready_promise.get_future());

	std::chrono::time_point<std::chrono::high_resolution_clock> start;

	auto fun1 = [&, ready_future]() -> std::chrono::duration<double, std::milli> {
			t1_ready_promise.set_value();
			ready_future.wait(); // waits for the signal from main()
			return std::chrono::high_resolution_clock::now() - start;
		};

	auto fun2 = [&, ready_future]() -> std::chrono::duration<double, std::milli> {
		t2_ready_promise.set_value();
		ready_future.wait(); // waits for the signal from main()
		return std::chrono::high_resolution_clock::now() - start;
	};

	auto fut1 = t1_ready_promise.get_future();
	auto fut2 = t2_ready_promise.get_future();

	auto result1 = std::async(std::launch::async, fun1);
	auto result2 = std::async(std::launch::async, fun2);

	// wait for the threads to become ready
	fut1.wait();
	fut2.wait();

	// the threads are ready, start the clock
	start = std::chrono::high_resolution_clock::now();

	// signal the threads to go
	ready_promise.set_value();

	std::cout << "Thread 1 received the signal " << result1.get().count() << " ms after start\n"
		<< "Thread 2 received the signal " << result2.get().count() << " ms after start\n";

	return 0;
}

///
// reference: https://en.cppreference.com/w/cpp/thread/shared_future/wait
int fib(int n)
{
	if (n < 3) return 1;
	else return fib(n - 1) + fib(n - 2);
}

int test_shared_future_2()
{
	// 将std::shared_future<int>调整为std::future<int>也是正确的
	std::shared_future<int> f1 = std::async(std::launch::async, []() { return fib(20); });
	std::shared_future<int> f2 = std::async(std::launch::async, []() { return fib(25); });

	std::cout << "waiting...\n";
	f1.wait();
	f2.wait();

	std::cout << "f1: " << f1.get() << '\n';
	std::cout << "f2: " << f2.get() << '\n';

	return 0;
}

///
// reference: https://en.cppreference.com/w/cpp/thread/shared_future/wait_for
int test_shared_future_3()
{
	// 将std::shared_future<int>调整为std::future<int>也是正确的
	std::shared_future<int> future = std::async(std::launch::async, [](){ 
        std::this_thread::sleep_for(std::chrono::seconds(3));
        return 8;  
    }); 
 
    std::cout << "waiting...\n";
    std::future_status status;
    do {
        status = future.wait_for(std::chrono::seconds(1));
        if (status == std::future_status::deferred) {
            std::cout << "deferred\n";
        } else if (status == std::future_status::timeout) {
            std::cout << "timeout\n";
        } else if (status == std::future_status::ready) {
            std::cout << "ready!\n";
        }
    } while (status != std::future_status::ready); 
 
    std::cout << "result is " << future.get() << '\n';

	return 0;
}

} // namespace future_

GitHubhttps://github.com/fengbingchun/Messy_Test

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11中std::shared_future的使用 的相关文章

  • C++中static_cast/const_cast/dynamic_cast/reinterpret_cast的区别和使用

    C风格的强制转换较简单 如将float a转换为int b 则可以这样 b int a 或者b int a C 类型转换分为隐式类型转换和显示类型转换 隐式类型转换又称为标准转换 包括以下几种情况 1 算术转换 在混合类型的算术表达式中 最
  • C和C++安全编码笔记:整数安全

    5 1 整数安全导论 整数由包括0的自然数 0 1 2 3 和非零自然数的负数 1 2 3 构成 5 2 整数数据类型 整数类型提供了整数数学集合的一个有限子集的模型 一个具有整数类型的对象的值是附着在这个对象上的数学值 一个具有整数类型的
  • C++/C++11中头文件algorithm的使用

  • C++11中模板类std::enable_shared_from_this的使用

    C 11中的模板类template
  • 在Ubuntu 18.04上支持C++17的std::filesystem的方法

    在Ubuntu 18 04上通过命令sudo apt install gcc g 安装的gcc g 版本为7 5 此版本并不直接支持filesystem 如下图所示 Ubuntu 18 04上的g 7 5支持experimental的fil
  • C++11容器中新增加的emplace相关函数的使用

    C 11中 针对顺序容器 如vector deque list 新标准引入了三个新成员 emplace front emplace和emplace back 这些操作构造而不是拷贝元素 这些操作分别对应push front insert和p
  • C++11中std::function的使用

    类模版std function是一种通用 多态的函数封装 std function的实例可以对任何可以调用的目标实体进行存储 复制 和调用操作 这些目标实体包括普通函数 Lambda表达式 函数指针 以及其它函数对象等 通过std func
  • C和C++安全编码笔记:文件I/O

    C和C 程序通常会对文件进行读写 并将此作为它们正常操作的一部分 不计其数的漏洞正是由这些程序与文件系统 其操作由底层操作系统定义 交互方式的不规则性而产生的 这些漏洞最常由文件的识别问题 特权管理不善 以及竞争条件导致 8 1 文件I O
  • 提高C++性能的编程技术笔记:引用计数+测试代码

    引用计数 reference counting 基本思想是将销毁对象的职责从客户端代码转移到对象本身 对象跟踪记录自身当前被引用的数目 在引用计数达到零时自行销毁 换句话说 对象不再被使用时自行销毁 引用计数和执行速度之间的关系是与上下文紧
  • Linux下多线程编程互斥锁和条件变量的简单使用

    Linux下的多线程遵循POSIX线程接口 称为pthread 编写Linux下的多线程程序 需要使用头文件pthread h 链接时需要使用库libpthread a 线程是进程的一个实体 是CPU调度和分派的基本单位 它是比进程更小的能
  • 程序员的自我修养--链接、装载与库笔记:Linux共享库的组织

    共享库 Shared Library 概念 其实从文件结构上来讲 共享库和共享对象没什么区别 Linux下的共享库就是普通的ELF共享对象 由于共享对象可以被各个程序之间共享 所以它也就成为了库的很好的存在形式 很多库的开发者都以共享对象的
  • 内存检测工具Dr. Memory的使用

    Dr Memory是一个内存调试工具 它是一个开源免费的内存检测工具 它能够及时发现内存相关的编程错误 比如未初始化访问 内存非法访问 数组越界读 写 以及内存泄露等 它可以在Linux Windows Mac OS和Android操作系统
  • C++中的封装、继承、多态

    封装 encapsulation 就是将抽象得到的数据和行为 或功能 相结合 形成一个有机的整体 也就是将数据与操作数据的源代码进行有机的结合 形成 类 其中数据和函数都是类的成员 封装的目的是增强安全性和简化编程 使用者不必了解具体的实现
  • C++中typeid的使用

    RTTI Run TimeType Information 运行时类型信息 它提供了运行时确定对象类型的方法 在C 中 为了支持RTTI提供了两个操作符 dynamic cast和typeid The typeid operator pro
  • 程序员的自我修养--链接、装载与库笔记:目标文件里有什么

    编译器编译源代码后生成的文件叫做目标文件 目标文件从结构上讲 它是已经编译后的可执行文件格式 只是还没有经过链接的过程 其中可能有些符号或有些地址还没有被调整 其实它本身就是按照可执行文件格式存储的 只是跟真正的可执行文件在结构上稍有不同
  • 概率论中伯努利分布(bernoulli distribution)介绍及C++11中std::bernoulli_distribution的使用

    Bernoulli分布 Bernoulli distribution 是单个二值随机变量的分布 它由单个参数 0 1 给出了随机变量等于1的概率 它具有如下的一些性质 P x 1 P x 0 1 P x x x 1 1 x Ex x Var
  • C/C++中#pragma once的使用

    在C C 中 为了避免同一个文件被include多次 有两种方式 一种是 ifndef方式 一种是 pragma once方式 在头文件的最开始加入 ifndef SOME UNIQUE NAME HERE define SOME UNIQ
  • C++11中std::shared_future的使用

    C 11中的std shared future是个模板类 与std future类似 std shared future提供了一种访问异步操作结果的机制 不同于std future std shared future允许多个线程等待同一个共
  • 开源库jemalloc简介

    jemalloc是通用的malloc 3 实现 它强调避免碎片和可扩展的并发支持 它的源码位于https github com jemalloc jemalloc 最新稳定版本为5 2 1 glibc的内存分配算法是基于dlmalloc实现
  • C++17中utf-8 character literal的使用

    一个形如42的值被称作字面值常量 literal 这样的值一望而知 每个字面值常量都对应一种数据类型 字面值常量的形式和值决定了它的数据类型 由单引号括起来的一个字符称为char型字面值 双引号括起来的零个或多个字符则构成字符串型字面值 字

随机推荐

  • 百度网盘无法登陆,二维码不显示,密码、验证码登陆显示‘网络异常’解决方法

    如图所示 二维码加载不出来 账号也不能登陆 但是其他软件一切正常 IE重置 防火墙 注册表 卸载重装 各种方法都无法解决 解决办法 连接手机WiFi后二维码加载出来 问题解决 所以换一个网登陆就可以了
  • linux 和 windows usb插拔侦测

    1 windowsU口探测事件 设备事件 WM DEVICECHANGE 首先要创建一个窗口 把设备事件和窗口关联 HWND h CreateWindow TEXT USB EVENT TEXT 0 0 0 0 0 0 0 GetModul
  • c语言经典程序合集

    1 c语言计算自然数之和 计算自然数和 include
  • SpringBoot+ Mybatis plus 配置多个数据源 (MySql)

    首先配置 yml 然后创建对应的 配置文件 然后复制下方的代码 进行粘贴 Configuration MapperScan basePackages com example chassis mapper chassis mapper sql
  • 关于一个栈的输入顺序是a,b,c,d,e则下列序列中不可能是出栈顺序

    经常在笔试的时候会看见这样类似的笔试题 就是关于一个栈的输入顺序是a b c d e则下列序列中不可能是出栈顺序 很多人都知道栈是先进后出 但是还是做好这道题 以一道题目为例给大家讲讲这道题目应该怎么做 题目 一个栈的输入顺序是a b c
  • 【Linux】深入理解文件操作

    文章目录 初次谈论文件 重温C语言文件操作 系统文件操作接口 open write read 再次谈论文件 文件描述符 文件描述符的分配规则 重定向 什么是重定向 重定向的本质 系统调用接口实现重定向 lt gt gt gt 初次谈论文件
  • Spring Boot中获取当前Request和Response实例的方法

    获取Request HttpServletRequest request ServletRequestAttributes RequestContextHolder getRequestAttributes getRequest 获取Res
  • uni-app在App平台如何实现升级更新?

    使用 uni app 开发 可将代码编译到iOS Android 微信小程序等多个平台 升级时也需考虑多平台同步升级 uni app发布为小程序的升级模式较简单 只需将开发完的代码提交小程序后台 待审核通过后用户将自动升级 App端的升级
  • STM32CubeIDE(串口)

    目录 一 轮询模式 1 1 配置USART2为异步模式 1 2 500ms发送一次消息 1 3 通信结果 1 4 串口控制LED 二 中断收发 2 1 开启中断 2 2 中断发送接收 2 2 1 中断发送只需要调用接口 2 2 2 中断接收
  • 二、文件管理命令

    2 文件管理命令 2 1文件管理 2 1 1touch新建文件指令 touch 当文件不存在时命令为新建文件 当文件存在时命令为修改文件时间戳 touch file1 file2 新建多个文件 touch t 11111111 11 修改文
  • 【算法】邻居好说话——冒泡排序

    简化版的桶排序不仅仅有上一节所遗留的问题 更要命的是 它非常浪费空间 例如需要排序数的范围是0 2100000000之间 那你则需要申请2100000001个变量 也就是说要写成int a 2100000001 因为我们需要用2100000
  • 关于EasyUI Datagrid JSON对象内嵌对象的取值问题

    如有这样一个JSON对象 1 goods 2 id 1 category id 1 name category1 name NameA shelfLife 12 3 id 1 category id 1 name category1 nam
  • 【hello Linux】进程间通信——共享内存

    目录 前言 1 System V共享内存 1 共享内存的理解 2 共享内存的使用步骤 3 共享内存的使用 1 共享内存的创建 查看共享内存 2 共享内存的释放 3 共享内存的挂接 4 共享内存的去挂接 4 共享内存的使用示例 1 两进程挂接
  • JavaWeb购物商城

    系统前台 前台用户操作 账号 test密码 test 登录页面 商品浏览 商品详情 购物车 订单页面 系统后台 后台用户操作 账号 admin密码 admin 用户登录页面 后台主页 添加商品 编辑商品 删除商品 数据库 部分代码 logi
  • matlab求傅里叶级数展开式_连续时间的傅里叶级数

    如果信号x t 是周期信号 那么对于所有t 存在一个最小正数T 使得x t x t T 其中 T 为这个周期信号的最小正周期 根据周期函数的周期性 x t x t N T N为整数 称为这个信号的基波频率 周期信号x t 也可以用周期复指数
  • 2020年全国高校计算机能力挑战赛初赛java语言解答

    题目1 统计从1到N的整数中 所有立方值的平方根为整数的数的格式 输入说明 整数N N lt 10000 输出说明 符合条件的数的个数 如4 3 64 8 2 输入样例 10 输出样例 3 说明 样例中符合条件的3个数是1 4 9 publ
  • Redis系列之安装配置

    前言 缓存Redis的讲解 作为第一个开篇文章 我们不谈高深的东西 从以下几个方面介绍下Redis 简介 安装 配置 启动 OK 下面我们就开始今天的缓存之旅吧 什么是Redis Redis是以Key value形式存储 和传统的关系型数据
  • Itext7填充PDF表单中文无法显示,‘凉’不显示问题

    Itext7填充PDF表单中文无法显示 凉 不显示问题 添加依赖
  • C#使用Sqlite总结

    1 下载Sqlite的dll 页面地址 http system data sqlite org index html doc trunk www downloads wiki 基于本项目的版本 下载Setups for 32 bit Win
  • C++11中std::shared_future的使用

    C 11中的std shared future是个模板类 与std future类似 std shared future提供了一种访问异步操作结果的机制 不同于std future std shared future允许多个线程等待同一个共