[编程基础] C++多线程入门8-从线程返回值
原始C++标准仅支持单线程编程。新的C++标准(称为C++11或C++0x)于2011年发布。在C++11中,引入了新的线程库。因此运行本文程序需要C++至少符合C++11标准。
8 从线程返回值
8.1 使用说明
一个std::future对象可以与asych,std::packaged_task和std::promise一起使用。本文将主要关注将std::future与std::promise对象一起使用。很多时候,我们遇到希望线程返回结果的情况。现在的问题是如何做到这一点?
让我们举个例子假设在我们的应用程序中,我们创建了一个将压缩给定文件夹的线程,并且我们希望该线程返回新的zip文件名及其结果。现在,我们有两种方法:
使用指针在线程之间共享数据
将指针传递给新线程,此线程将设置其中的数据。在此之前,在主线程中使用条件变量继续等待。当新线程设置数据并向条件变量发送信号时,主线程将唤醒并从该指针获取数据。为了简单起见,我们使用了一个条件变量,一个互斥锁和一个指针(即3个项)来捕获返回的值。为那么问题将变得更加复杂。有没有一个简单的方法从线程返回值。答案是肯定的,使用std::future,让我们看看下一个解决方案。
C++11方式:使用std::future和std::promise
std::future是一个类模板,其对象存储将来的值。那么这future模板有什么用?实际上,一个std::future对象在内部存储了将来将分配的值,并且还提供了一种访问该值的机制,即使用get()成员函数。但是,如果有人尝试在get()函数可用之前访问future的此关联值,则get()函数将阻塞直到该值不可用。
std::promise也是一个类模板,其对象承诺将来会设置该值。每个std::promise对象都有一个关联的std::future对象,一旦std::promise对象设置了该值,它将给出该值。一个std::promise对象与其关联的std::future对象共享数据。让我们一步一步来看看,在Thread1中创建一个std::promise对象。
std::promise<int> promiseObj;
截至目前,该promise对象没有任何关联值。但是它提供了一个保证,肯定有人会在其中设置值,一旦设置了值,您就可以通过关联的std::future对象获得该值。但是现在假设线程1创建了这个promise对象并将其传递给线程2对象。现在,线程1如何知道何时线程2将在此promise对象中设置值?
答案是使用std::future对象。每个std::promise对象都有一个关联的std::future对象,其他对象可以通过该对象获取promise设置的值。
现在,线程1将把promiseObj传递给线程2。然后线程1将通过std::future的get函数获取线程2在std::promise中设置的值。
int val = futureObj.get();
但是,如果线程2尚未设置值,则此调用将被阻塞,直到线程2在promise对象中设置值,即
promiseObj.set_value(45);
在下图中查看完整流程:

让我们看一个完整的std::future和std::promise示例,
#include <iostream>
#include <thread>
#include <future>
void initiazer(std::promise<int> * promObj)
{
std::cout<<"Inside Thread"<<std::endl; promObj->set_value(35);
}
int main()
{
std::promise<int> promiseObj;
std::future<int> futureObj = promiseObj.get_future();
std::thread th(initiazer, &promiseObj);
std::cout<<futureObj.get()<<std::endl;
th.join();
return 0;
}
输出为:
Inside Thread
35
此外,如果您希望线程在不同的时间点返回多个值,则只需在线程中传递多个std::promise对象,然后从关联的多个std::future对象中获取多个返回值。在下一篇文章中,我们将看到如何将std::future与std::asych和std::packaged_task结合使用。
8.2 参考
[编程基础] C++多线程入门8-从线程返回值的更多相关文章
- [编程基础] C++多线程入门1-创建线程的三种不同方式
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 1 创建线程的三种不 ...
- [编程基础] C++多线程入门4-数据共享和资源竞争
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++ 11标准. 4 数据共享和资源 ...
- [编程基础] C++多线程入门7-条件变量介绍
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 7 条件变 ...
- [编程基础] C++多线程入门10-packaged_task示例
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 10 pa ...
- [编程基础] C++多线程入门9-async教程和示例
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 9 asy ...
- [编程基础] C++多线程入门3-小心地将参数传递给线程
原始C++标准仅支持单线程编程.新的C++标准(称为c++11或c++0x)于2011年发布.在c++11中,引入了新的线程库.因此运行本文程序需要C++至少符合c++11标准. 文章目录 3 小心地 ...
- [编程基础] C++多线程入门2-连接和分离线程
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 2 连接和 ...
- [编程基础] C++多线程入门6-事件处理的需求
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 6 事件处 ...
- [编程基础] C++多线程入门5-使用互斥锁解决资源竞争
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 5 使用互 ...
随机推荐
- AVX图像算法优化系列二: 使用AVX2指令集加速查表算法。
查表算法,无疑也是一种非常常用.有效而且快捷的算法,我们在很多算法的加速过程中都能看到他的影子,在图像处理中,尤其常用,比如我们常见的各种基于直方图的增强,可以说,在photoshop中的调整菜单里8 ...
- Charles的安装与使用
Charles是一款抓包工具,可以用来截取和发送手机APP上的各种请求 在windows上安装Charles,确保手机和电脑在同一个WIFI下,加上一些配置,就可以抓取手机上的APP请求 有能力的同学 ...
- 如何实现通过Leaflet加载dwg格式的CAD图
前言 在前面介绍了通过openlayers加载dwg格式的CAD图并与互联网地图叠加,openlayers功能很全面,但同时也很庞大,入门比较难,适合于大中型项目中.而在中小型项目中,一般用开源的 ...
- vue-router(路由嵌套)
文章目录 1.项目结构 2.路由嵌套 3.界面(使用elementui) 4.效果展示 1.项目结构 2.路由嵌套 import Vue from 'vue' import Router from ' ...
- 怎样在GitHub上建立仓库、以及怎样实现分支代码的合并。保姆级别的教程
GitHub官网地址:https://github.com/ 注意:前提是已经注册了GitHub 文章目录 第一步:创建一个新的仓库 第二步.创建一个分支 第三步.编辑和发布更改的内容 第四步.拉取请 ...
- go-zero docker-compose 搭建课件服务(七):prometheus+grafana服务监控
0.转载 go-zero docker-compose 搭建课件服务(七):prometheus+grafana服务监控 0.1源码地址 https://github.com/liuyuede123/ ...
- 3.httprunner-extract/.env/Testcase
参数关联-extract 场景:上一个接口的返回值,传给下一个接口当请求参数 extract:提取变量 $变量名 :引用变量 假设我们有如下场景 用户A登录之后,返回值返回用户UID,我们需要查询该用 ...
- OpenMP 入门
OpenMP 入门 简介 OpenMP 一个非常易用的共享内存的并行编程框架,它提供了一些非常简单易用的API,让编程人员从复杂的并发编程当中释放出来,专注于具体功能的实现.openmp 主要是通过编 ...
- C# 多线程访问之 SemaphoreSlim(信号量)【C# 进阶】
SemaphoreSlim 是对可同时访问某一共享资源或资源池的线程数加以限制的 Semaphore 的轻量替代,也可在等待时间预计很短的情况下用于在单个进程内等待. 由于 SemaphoreSlim ...
- mindxdl---common---db_handler.go
// Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.// Package common this file ...