IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> [modern c++] std::future 与 std::async / std::promise / std::packaged_task 一起使用 -> 正文阅读

[C++知识库][modern c++] std::future 与 std::async / std::promise / std::packaged_task 一起使用

描述:

std::future 可以用来获取所有异步操作的结果,一般情况下 std::future 都会和 std::async , std::promise 或 std::packaged_task 一起使用。

std::future 有一个 valid 状态,当且仅当其valid状态时true时,才可以使用它,std::async , std::promise 或 std::packaged_task 创建的 std::future 都是 valid == true的 ,如果自行使用 std::future 的构造函数创建一个实例,那么它一定不是 valid 的,可以把 valid 状态当做一个 std::future 是否和某个异步任务相关联的标志,valid == false 代表当前 std::future 实际没有关联任何异步任务。

因为其内部已经有关联的异步任务了,可以把valid看作是std::future是否初始化完成的标志,一般初始化都比较快,所以正常情况下invalid状态很少出现,一般只在没指定异步任务时出现。另外如果使用std::move把异步任务从某个std::future转移给另一个,那么之前那个std::future会变成invalid状态。

std::future 有两套阻塞等待函数 waitX() 和 get(), waitX()会在任务没有执行完毕的情况下一直阻塞或者阻塞等待一段时间,但是不会改变std::future的valid状态

get() 会阻塞等待任务执行完毕并且返回任务的返回值,同时会把 std::future 的状态变成 invalid 状态。这个时候只有重新做 move 或者重新通过?std::async , std::promise 或 std::packaged_task 才能再次激活 std::future。

换句话说,每个std::future 只能 get 一次,重复 get 会导致抛异常,进而崩溃。

鉴于不能重复 get 的问题,很多情况下我们只和 void 返回值的可调用对象一起使用,然后不去调用get函数,只用wait作同步只用。

与 std::async 一起使用

gcc 2.cpp -pthread -o 2

#include <future>
#include <string>
#include <mutex>
#include <stdio.h>
#include <unistd.h>
#include <thread>
#include <iostream>
 

std::atomic<bool> bbb{false};

int func()
{
	while(!bbb){
		sleep(1);
	}
	std::cout << "func stop" << std::endl;
	
	return 99;
}
 
int main()
{
	std::future<int> ret;
	
	//没有关联任何任务,因此是invalid
	if(ret.valid()){						
		std::cout << "valid" << std::endl;
	}else{
		std::cout << "invalid" << std::endl;
	}
	
	std::cout << "----------" << std::endl;
	
	std::future<int> ret1 = std::async<int()>(std::launch::async,func);
	
	if(ret1.valid()){
		std::cout << "before move ret1 : valid" << std::endl;
	}else{
		std::cout << "before move  ret1 : invalid" << std::endl;
	}
	
	ret = std::move(ret1);
	
	if(ret1.valid()){
		std::cout << "after move ret1 : valid" << std::endl;
	}else{
		std::cout << "after : invalid" << std::endl;
	}
	
	std::cout << "----------" << std::endl;
	
	//关联任务,因此是valid
	if(ret.valid()){
		std::cout << "valid" << std::endl;
	}else{
		std::cout << "invalid" << std::endl;
	}
	
	std::cout << "----------" << std::endl;
	
	//把任务停掉,仍然是valid
	bbb = true;
	//等待可执行对象执行完毕,如果在wait之前已经执行完毕,那么这里直接返回
	ret.wait();
	
	//wait 只是等待异步任务结束,不会重置当前std::future,因此还是valid
	if(ret.valid()){
		std::cout << "valid" << std::endl;
	}else{
		std::cout << "invalid" << std::endl;
	}
	
	std::cout << "----------" << std::endl;
	
	//get 会等待异步任务结束并获取结果,get会重置 std::future,因此会变成 invalid
	int result = ret.get();
	
	if(ret.valid()){
		std::cout << "valid" << std::endl;
	}else{
		std::cout << "invalid" << std::endl;
	}
	
}

与 std::promise一起使用

todo

与 std::packaged_task?一起使用

todo

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-03 10:32:27  更:2022-07-03 10:32:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:58:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码