首页 > 编程语言 >[编程基础] C++多线程入门8-从线程返回值

[编程基础] C++多线程入门8-从线程返回值

时间:2022-12-19 21:55:07浏览次数:66  
标签:std 对象 C++ future promise 线程 多线程

date: 2020-05-29 17:09:34 +0800
tags:
  - 编程基础

原始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 参考

https://thispointer.com//c11-multithreading-part-8-stdfuture-stdpromise-and-returning-values-from-thread/

标签:std,对象,C++,future,promise,线程,多线程
From: https://www.cnblogs.com/luohenyueji/p/16993186.html

相关文章

  • [C++]LeetCode 2502 设计内存分配器
    [C++]LeetCode2502.设计内存分配器题目描述Difficulty:中等RelatedTopics:设计,数组,哈希表,模拟给你一个整数n,表示下标从0开始的内存数组的大小。所有内存......
  • [C++]LeetCode 1971 寻找图中是否存在路径
    [C++]LeetCode1971.寻找图中是否存在路径题目描述Difficulty:简单RelatedTopics:深度优先搜索,广度优先搜索,并查集,图有一个具有n个顶点的双向图,其中每个......
  • C++ 随机数生成器 mt19937
    一下代码来自官方示例//mersenne_twister_engineconstructor#include<iostream>#include<chrono>#include<random>intmain(){//obtainaseedfromthe......
  • C++实现顺序表相关操作
    //顺序表#include<iostream>#include<cstdlib>//C中stdlib.h动态分配内存usingnamespacestd;#defineOK1#defineERROR0#defineOVERFLOW-2#defineMAXSIZE100typede......
  • 剑指offer 数字在排序数组中出现的次数(C++)
    题目描述统计一个数字在排序数组中出现的次数。代码实现classSolution{public:intGetNumberOfK(vector<int>data,intk){if(data.empty())re......
  • 剑指offer 二叉树的深度(C++)
    题目描述输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。代码实现/*structTreeNode{intval;......
  • 剑指offer 字符串的排列(C++)
    题目描述输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。输入描述:......
  • 剑指offer 二叉树的镜像(C++)
    问题描述操作给定的二叉树,将其变换为源二叉树的镜像。输入描述:二叉树的镜像定义:源二叉树8/\610/\/\57911镜像二叉树......
  • LeetCode 两数之和,三数之和,最接近的三数之和,四数之和(C++)
    1.两数之和问题描述给定一个整数数组​​nums​​​和一个目标值​​target​​,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。你可以假设每种输入......
  • LeetCode 有关二叉树的算法题目(C++)
    0、NULL与nullptr的区别在C语言中,​​NULL​​​通常被定义为:​​#defineNULL((void*)0)​​​。因为在C语言中把空指针赋给​​int​​​和​​char​​​指针的时候,发......