C++多线程编程(3):接收线程处理函数的返回值

news2024/11/17 15:31:24

文章首发于我的个人博客:欢迎大佬们来逛逛

文章目录

  • 处理带返回值的函数
    • async
    • packaged_task
    • promise

处理带返回值的函数

有三种方法:

  • async
  • packaged_task
  • promise

async

第一种方法是使用 async 函数。

步骤:

  1. 使用 async 创建线程处理函数
  2. 使用 .get() 获取返回值。

async函数具有两个属性

  • launch::async(默认):表示创建线程处理函数并且立刻执行
  • launch::defered:延期,当使用wait或者get的时候才会执行线程处理函数

async函数的返回值:std::future 类型,通过调用其 get 方法获取返回值

下面分别演示了普通函数类的成员函数以及 defered 的作用:

int value1(int num) {
	return num; 
}

//类对象
class Foo {
public:
	Foo() {}
	int getValue(int num) {
		std::chrono::milliseconds duration(2000);
		std::this_thread::sleep_for(duration);
		return num * 2;
	}
};

void testAsync() {
	//直接执行,默认是launch::async
	std::future<int> res1 = std::async(value1, 100);
	std::cout << res1.get() << '\n';

	Foo m{};
	//类成员函数
	std::future<int> res2 = std::async(&Foo::getValue, &m, 200);
	std::cout << res2.get() << '\n';

	//不会立刻执行
	auto res3 = std::async(std::launch::deferred, &Foo::getValue, m, 400);
	//调用get,执行线程
	std::cout << res3.get() << '\n';
}

在这里插入图片描述


packaged_task

第二种方法是使用 packaged_task 方法

步骤:

  1. 使用 packaged_task 来包装线程处理函数
  2. 然后将这个包装好的函数加入到线程 thread 中,并且执行线程处理函数
  3. 最后使用这个 packaged_task 调用 get_future 来获取 future,然后调用 get 获取值。

package_task 函数包装语法:

//包装普通函数
std::packaged_task<返回类型(形参列表)> pack1(函数名称);

//包装类的成员函数
std::packaged_task<返回类型(形参列表)> pack2(bind(函数地址,成员变量地址,placeholders占位符))

//包装lambda表达式
std::packaged_task<int(int)> pack3([](形参列表){
		xxxx
		return xxx;
});

可以看到对于类的成员函数是相对比较复杂的。

void testPackaged_task() {
	//1. 普通函数的包装
	std::packaged_task<int(int)> pack1(value1);
	std::thread t1(std::ref(pack1),100);  //转换为&&
	t1.join();
	std::cout << pack1.get_future().get() << '\n';

	//2. 类中成员函数的包装
	Foo m{};
	std::packaged_task<int(int)> pack2(std::bind(&Foo::getValue, &m, std::placeholders::_1));
	std::thread t2(std::ref(pack2), 200);
	t2.join();
	std::cout << pack2.get_future().get() << '\n';
	
	//3. lambda表达式
	std::packaged_task<int(int)> pack3([](int num) {
		std::cout << "id: " << std::this_thread::get_id() << '\n';
		return num * 2;
	});
	std::thread t3(std::ref(pack3),300);
	t3.join();
	std::cout << pack3.get_future().get() << '\n';
}

在这里插入图片描述


promise

第三种方法是使用 promise 类型

步骤:

  1. 传递 promise 类型的变量到线程处理函数中。
  2. 我们正常执行线程处理函数即可,无需使用return语句,在操作完成后把需要的值 set_value 设置为promise 的值。
  3. 然后使用 thread 创建并且执行线程处理函数。
  4. 然后我们就可以在外部使用 .get_future 获取 future对象, 继而 .get 获取值。

这种方法的特点:

  • 无需显示设置 return 语句
  • 需要往线程处理函数添加一个额外的 promise 类型的参数。

例如这个是我们的线程处理函数,我们需要返回 num *3, 但是现在我们添加一个promise 类型的参数(注意是引用),然后直接 set_value 即可,然后再外部就可以直接访问这个值了。

void testThread(std::promise<int>& pms, int num) {
	std::cout << get_id() << '\n';
	pms.set_value(num * 3);
}
  • 返回线程处理函数的值:
std::promise<int> pms;
std::thread t1(testThread, std::ref(pms), 100);
t1.join();
auto num = pms.get_future().get();
std::cout << num << '\n';

这种方法也可以传递线程的值到另一个线程处理函数中:

有一个 testGetValueThread 线程函数,我们需要把刚才获取的 num*3 的值再传递进去,则可以在这个线程函数内调用 .get_future().get() 来传递参数。

下面是两种方法,这里使用了函数重载作为线程处理函数,需要使用static_cast来避免重载歧义。

通过static_cast消除重载函数的歧义

void testGetValueThread(std::promise<int>& pms) {
	std::cout << "获取值: " << pms.get_future().get() << '\n';
}
void testGetValueThread(int num) {
	std::cout << "获取值: " << num << '\n';
}

...

std::promise<int> pms2;
	pms2.set_value(99);
	//值传递到其他线程中
	//通过static_cast消除重载函数的歧义
	std::thread t2(static_cast<void(*)(std::promise<int>&)>(testGetValueThread), std::ref(pms2));
	t2.join();

	std::thread t3(static_cast<void(*)(int)>(testGetValueThread), num);
	t3.join();

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1226695.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pom.xml格式化快捷键

在软件开发和编程领域&#xff0c;"格式化"通常指的是将代码按照一定的规范和风格进行排列&#xff0c;以提高代码的可读性和维护性。格式化代码有助于使代码结构清晰、统一&#xff0c;并符合特定的编码规范。 格式化可以包括以下方面&#xff1a; 缩进&#xff1a…

HR应用在线人才测评,给企业招聘带来的好处

一、什么是人才测评&#xff1f; 人才测评是指运用一系列的科学方法&#xff0c;对人的基本素质&#xff0c;专业能力&#xff0c;心理健康&#xff0c;性格进行选拔&#xff0c;评价及发展人才的一种科学方法。近十多年&#xff0c;它被广泛运用于国有大型企业的人才招聘和人…

策略模式在数据接收和发送场景的应用(升级版)

1.背景 在数据接收和发送场景打算使用了 if else 进行判断&#xff1a; if("A".equals(system)){ASystem.sync("向A同步数据"); } if("B".equals(system)){BSystem.sync("向B同步数据"); } ... 非常麻烦&#xff0c;需求多了很臃肿&…

AI对开发者职业的影响,保持领先的7 个行动指南

在不断发展的技术领域&#xff0c;人工智能(AI)已经成为一股变革性的力量&#xff0c;重塑了行业&#xff0c;重新定义了我们解决问题的方式。对于开发人员来说&#xff0c;学习AI的决定不仅仅是为了保持相关性&#xff0c;而是在他们的职业生涯中开启一个新的可能性维度。 1.…

Scalable Exact Inference in Multi-Output Gaussian Processes

Orthogonal Instantaneous Linear Mixing Model TY are m-dimensional summaries&#xff0c;ILMM means ‘Instantaneous Linear Mixing Model’&#xff0c;OILMM means ‘Orthogonal Instantaneous Linear Mixing Model’ 辅助信息 作者未提供代码

【接口测试】最细Fiddle抓包辅助接口实战,抓包全过程总结...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、为什么需要抓包…

Python开源项目周排行 2023年第38周

#2023年第38周2023年11月19日1easybc用于解析分组加密算法的输入 [EasyDC] 程序&#xff0c;然后根据差分密码分析对分组加密算法进行安全分析。它支持以下功能&#xff1a; EasyBC 的解释器。 基于 SMT 的方法&#xff0c;用于确定各种密码操作的分支数。 S-box 中的差分传播建…

C++多线程编程(1):线程的创建方式

文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 文章目录 进行与线程C中如何实现多线程创建线程的多种方式无参函数lambda表达式常成员函数not常成员引用函数智能指针仿函数类的普通成员函数综合测试 进行与线程 多线程是指多个线程并发执行的过程。 进程与线程的关系&…

WIFI版本云音响设置教程腾讯云平台版本

文章目录 WIFI版本云音响设置教程腾讯云平台版本一、申请设备三元素1.腾讯云物联网平台2.创建产品3.设置产品参数4.添加设备5.获取三元素 二、设置设备三元素1.打开MQTTConfigTools2.计算MQTT参数3.使用windows电脑的WIFI连接到设备热点4.设置参数 三、腾讯云物联网套件协议使用…

Linux基础全整理 从入门到放弃,一些想说的话

阅读目录 断更后一些想说的话用户useraddpasswdpasswd文件详解 chageusermoduserdelshadow 文件格式切换用户 用户组groupaddgroup文件格式groupmodgroupdel登陆远程机器 磁盘RAIDraid0&#xff08;安装系统&#xff09;raid1&#xff08;存放数据&#xff09;raid 5&#xff0…

盘点54个Python实用工具源码Python爱好者不容错过

盘点54个Python实用工具源码Python爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1OXyEh-Yy3JI90jvn6d6wRw?pwd8888 提取码&#xff1a;8888 项目名称 7z辅助破解工…

基于冠状病毒群体免疫算法优化概率神经网络PNN的分类预测 - 附代码

基于冠状病毒群体免疫算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于冠状病毒群体免疫算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于冠状病毒群体免疫优化的PNN网络5.测试结果6.参考文献7.Matlab代码 …

漂亮的pyqt6皮肤 PyOneDark_Qt_Widgets_Modern_GUIPublic

大家先看看界面图&#xff0c;真的很漂亮&#xff1a; github地址&#xff1a;GitHub - Wanderson-Magalhaes/PyOneDark_Qt_Widgets_Modern_GUI 作者还录了教程&#xff1a; TUTORIALS: Tutorial 01: https://youtu.be/QQGlTGYCMg0 Tutorial 02: https://youtu.be/LwKre2proDk…

Halcon (4):如何开始自学

文章目录 文章专栏前言Halcon文档Halcon基础案例文档英语阅读建议 结论 文章专栏 Halcon开发 前言 在我完成上一篇代码&#xff0c;halcon基础窗口事件写完了之后&#xff0c;我已经基本掌握了如何写一个简单的halcon程序。后面我学习新的知识的时候感觉遇到了瓶颈。因为网上没…

【C++】:模板进阶

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关C模板进阶的知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数…

『亚马逊云科技产品测评』活动征文|借助AWS EC2搭建服务器群组运维系统Zabbix+spug

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 本文基于以下软硬件工具&#xff1a; aws ec2 frp-0.52.3 zabbix 6…

Web之JavaScript(jQuery)笔记

Web之HTML、CSS、JavaScript 三、JavaScriptJS调试变量自定义函数数据类型及转换运算符优先级内置函数数组事件DOM(Document Object Model 文档对象模型)jQuery Web之HTML笔记 Web之CSS笔记 三、JavaScript JavaScript&#xff08;简称“JS”&#xff09;是一种轻量级的面向对…

心怀祖国放眼世界 爱国人士华国中应邀参加美国旧金山2023(APEC)峰会

据相关媒体美国旧金山报道:2023亚太经合组织&#xff08;APEC&#xff09;领导人非正式会议将于11月15日至17日在美国旧金山召开。11月11日&#xff0c;本年度APEC高级财政官员和部长会晤在旧金山率先启动&#xff0c;APEC CEO峰会将于11月14日至16日开幕。著名爱国人士、亚太一…

《向量数据库指南》——亚马逊云科技向量数据库揭秘:点亮数据未来!

在我们讨论亚马逊云科技向量数据库之前,我们必须先搞懂向量数据库。 那么,向量数据库是什么呢?简单来说,向量数据库就是一种专门用于处理和查询向量数据的数据库。与传统数据库以表格形式组织和存储数据不同,向量数据库采用多维数值数组的形式处理和存储数据。它的主要目标…

和解电话(匿名电话)/情侣拉黑联系电话/虚拟号/虚拟中间号/拉黑联系项目代码

和解电话&#xff0c;又名匿名电话 使用中间号转接到被叫人&#xff0c;不显示呼叫人号码&#xff0c;类似美团隐私号 呼叫人A->中间号B->被叫人C 演示地址&#xff1a;微信打开(http://sms.test.4php.top/sms/phone) 实现代码如下 <section class"section&q…