创建线程时传递参数给线程

在C++中,可以使用 std::thread 来创建和管理线程,同时可以通过几种方式将参数传递给线程函数。这些方法包括使用值传递、引用传递和指针传递。下面将对这些方法进行详细讲解并给出相应的代码示例。

1. 值传递参数

当你创建线程并希望传递参数时,可以直接将参数作为 std::thread 构造函数的参数传递。这会将参数的副本传递给线程。

示例代码:使用值传递参数

#include <iostream>
#include <thread>void thread_function(int value) {std::cout << "Thread received value: " << value << std::endl;
}int main() {int value_to_pass = 10;std::thread t(thread_function, value_to_pass); // 传递参数t.join(); // 等待线程完成return 0;
}

2. 引用传递参数

如果希望传递参数的引用,以避免复制开销,可以使用 std::ref() 来包装参数。这对于大型对象特别有用。

示例代码:使用引用传递参数

#include <iostream>
#include <thread>
#include <vector>
#include <functional> // 为 std::ref 使用void thread_function(std::vector<int>& vec) {vec.push_back(5); // 修改传入的向量std::cout << "Thread modified vector to include 5." << std::endl;
}int main() {std::vector<int> vec;std::thread t(thread_function, std::ref(vec)); // 传递引用t.join(); // 等待线程完成std::cout << "Vector size after thread: " << vec.size() << std::endl; // 输出:1return 0;
}

3. 传递结构体或类对象

可以通过传递结构体或类对象的方式将多个参数传递给线程。这个过程与使用值传递或引用传递相结合,可以根据需要进行操作。

示例代码:传递结构体作为参数

#include <iostream>
#include <thread>struct ThreadData {int id;std::string message;
};void thread_function(ThreadData data) {std::cout << "Thread " << data.id << ": " << data.message << std::endl;
}int main() {ThreadData data = {1, "Hello from thread!"};std::thread t(thread_function, data); // 传递结构体t.join(); // 等待线程完成return 0;
}

4. 线程接受多个参数

通过将多个参数传递给线程,可以直接在创建 std::thread 时指定多个参数。

示例代码:传递多个参数

#include <iostream>
#include <thread>void thread_function(int a, double b) {std::cout << "Thread received integer: " << a << " and double: " << b << std::endl;
}int main() {std::thread t(thread_function, 42, 3.14); // 传递多个参数t.join(); // 等待线程完成return 0;
}

总结

通过以上示例,我们展示了在C++中创建线程及传递参数的不同方式:

  1. 值传递:直接传递参数的副本。
  2. 引用传递:使用 std::ref() 传递对象的引用,避免复制。
  3. 结构体或类对象:将多个参数封装到一个结构体中进行传递。
  4. 多个参数传递:在创建线程时可以直接传递多个参数。

这种灵活性使得在多线程编程中能够更好地管理数据和资源。根据具体的应用场景,可以选择合适的参数传递方式。

在C++中,除了使用常规的函数作为线程的入口点外,我们还可以使用 lambda 表达式 和 类的成员函数。这两种方式可以使代码更加灵活和简洁。下面将提供示例代码,展示如何使用这两种形式创建线程并传递参数。

1. 使用 Lambda 表达式

Lambda 表达式可以直接在创建线程时定义,非常适合进行简短的任务。在 lambda 中,可以捕获外部变量并将其用于线程中。

示例代码:使用 Lambda 表达式

#include <iostream>
#include <thread>int main() {int value = 42;// 创建线程时使用 lambda 表达式std::thread t([value]() {std::cout << "Thread is running, received value: " << value << std::endl;});t.join(); // 等待线程完成return 0;
}

2. 使用 类的成员函数

如果你有一个对象,并希望使用该对象的成员函数作为线程的入口,可以使用 std::thread 的构造函数将对象的成员函数与对象本身一同传递。必须确保对象在调用之前保持有效。

示例代码:使用类的成员函数

#include <iostream>
#include <thread>class MyClass {
public:void member_function(int value) {std::cout << "Thread running from member function, received value: " << value << std::endl;}
};int main() {MyClass obj;int value = 100;// 创建线程并传递成员函数和对象std::thread t(&MyClass::member_function, &obj, value);t.join(); // 等待线程完成return 0;
}

3. Lambda 表达式与复杂参数

Lambda 表达式还可以接受多个参数,并且可以捕获外部变量,例如引用或指针。下面的示例展示了如何捕获引用。

示例代码:Lambda 表达式捕获引用

#include <iostream>
#include <thread>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3};// 使用 lambda 表达式修改 vectorstd::thread t([&vec]() {vec.push_back(4);std::cout << "Thread modified vector." << std::endl;});t.join(); // 等待线程完成std::cout << "Vector size after thread: " << vec.size() << std::endl; // 输出:4return 0;
}

4. 成员函数与多个参数

可以通过类的成员函数传递多个参数。在实例化 std::thread 时,将这些参数传递给成员函数。

示例代码:成员函数与多个参数

#include <iostream>
#include <thread>class MyClass {
public:void member_function(int a, double b) {std::cout << "Thread from member function, received int: " << a<< " and double: " << b << std::endl;}
};int main() {MyClass obj;// 创建线程并传递成员函数及参数std::thread t(&MyClass::member_function, &obj, 42, 3.14);t.join(); // 等待线程完成return 0;
}

总结

通过以上示例,我们展示了如何使用 lambda 表达式 和 类的成员函数 在C++中创建线程并传递参数。

  • Lambda 表达式:能够快速定义匿名函数,并且能够捕获外部变量。适合简单的任务。
  • 类的成员函数:能在对象的上下文中执行功能,可以通过传递对象的指针来调用它们。适用于需要利用对象状态的情况。

这些方式可以使得多线程编程更灵活、更易读,开发者可以根据具体需求选择合适的方式。

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

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

相关文章

Linux下cgdb/gdb调试以及关于操作系统那些事

目录 一.gdb调试 1.1debug和release版本有什么区别? 1.2性能优化 1.3gdb的使用 1.4cgdb的安装 二.什么是硬件 三.冯诺依曼体系 四.操作系统(OS) 4.1理解操作系统 4.1.1操作系统是什么? 4.1.2为什么要有操作系统? 4.1.3 OS-银行 4.1.4OS如何管理 理解库文件和系…

Kafka相关知识点(上)

为什么要使用消息队列&#xff1f; 使用消息队列的主要目的主要记住这几个关键词:解耦、异步、削峰填谷。 解耦: 在一个复杂的系统中&#xff0c;不同的模块或服务之间可能需要相互依赖&#xff0c;如果直接使用函数调用或者 API 调用的方式&#xff0c;会造成模块之间的耦合…

ureport配置方法

1、项目启动后登录这个网址&#xff0c;ip和端口自己系统的 http://localhost:8080/ureport/designer 点击这个地方&#xff0c;图标类似一个文件夹选择下图标注的两个文件&#xff0c;这两个文件就是eoa系统要用到的报表文件&#xff0c;还是点击类似文件夹图标的图标 正在上…

在Linux上搭建Minecraft服务器的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 在 Linux&#xff08;Ubuntu 12.04&#xff09;上设置 Minecraft 服务器是一个相当简单的任务&#xff0c;只需通过命令行即可完成。 在…

/检测是否json格式参数;对现在 上月时间参数;JS判断数组(数组对象)是否发现变化;js判断对象是否是空对象

//检测是否json格式参数 isValidJSON(str) { if (/^[\],:{}\s]*$/.test(str.replace(/\\["\\\/bfnrtu]/g, ). replace(/"[^"\\\n\r]*"|true|false|null|-?\d (?:\.\d*)?(?:[eE][ \-]?\d )?/g, ]). replace(/(?:^|:|,)(?:\s*\[) /g, ))) { return t…

Java学习路线:JUnit单元测试

目录 使用JUnit 导入依赖 使用Junit 添加前置/后置操作 当项目十分庞大时&#xff0c;如果想测试一个很小的功能&#xff0c;都要启动整个项目来测试&#xff0c;会很浪费时间。 那能否将某个小功能单独拆出来进行测试呢&#xff1f; 这就是单元测试的作用。而JUnit就是一…

RK3568平台(camera篇)车载摄像头串行器和解串器方案

一.串行器和解串器简介 SerDes是Serializer/Deserializer的缩写,即串行器和解串器。由于同轴线的传输延迟几乎可以忽略不计(ns级别),相当于将原来只能短距离传输的高速并行信号(MIPI/I2C/CLK等)的传输距离延长,真正做到高带宽、低延迟、长距离的数据传输。 串行器(Seri…

问:Redis为什么这么快?

Redis&#xff0c;全称Remote Dictionary Server&#xff0c;是一个开源的高性能键值对数据库。它以其卓越的性能、丰富的数据结构和灵活的使用方式&#xff0c;在现代互联网应用中扮演着重要角色。本文将探讨Redis之所以快的原因&#xff0c;包括其数据结构、内存管理、IO多路…

Qt 窗口部件的焦点策略

setFocusPolicy 函数是 Qt 框架中的一个成员函数&#xff0c;用于设置窗口部件&#xff08;widget&#xff09;的焦点策略&#xff08;focus policy&#xff09;。具体来说&#xff0c;Qt中的焦点策略&#xff08;Qt::FocusPolicy&#xff09;决定了控件是否可以通过键盘&#…

【A】【Maven项目热部署】将Maven项目热部署到远程tomcat服务器上

将Maven项目热部署到远程tomcat中 文章目录 将Maven项目热部署到远程tomcat中1.解决方案&#xff1a;2.实现3.Tomcat中的Root项目的配置和使用4.在tomcat-user.xml中配置远程服务器tomcat的账户信息5.修改 IP 访问权限6.登录ROOT项目&#xff0c;使用Manager App功能管理tomcat…

Scrum价值观

五大价值观 尊重&#xff0c;勇气&#xff0c;专注&#xff0c;承诺&#xff0c;开放 三大支柱&#xff08;经验主义的三大支柱&#xff09; 透明度&#xff0c;检查&#xff0c;适应 三大职责&#xff08;不是三大角色&#xff09; 产品负责人&#xff0c;开发人员&#xff0c…

过渡,2D,3D 转换

## 3D 转换 ### 1、旋转&#xff1a;rotateX、rotateY、rotateZ javascript transform: rotateX(360deg); //绕 X 轴旋转360度 transform: rotateY(360deg); //绕 Y 轴旋转360度 transform: rotateZ(360deg); //绕 Z 轴旋转360度 1. rotateY 举例&#xff1a; html…

【机器学习】26. 聚类评估方法

聚类评估方法 1. Unsupervised Measure1.1. Method 1: measure cohesion and separationSilhouette coefficient Method 2&#xff1a;Correlation between two similarity matricesMethod 3&#xff1a;Visual Inspection of similarity matrix 2. Supervised measures3. 决定…

YOLOv11改进策略【Backbone/主干网络】| ICLR-2023 替换骨干网络为:RevCol 一种新型神经网络设计范式

一、本文介绍 本文记录的是基于RevCol的YOLOv11目标检测改进方法研究。RevCol是一种新型神经网络设计范式,它由多个子网(列)及多级可逆连接构成,正向传播时特征逐渐解缠结且保持信息。可逆变换借鉴可逆神经网络思想,设计多级可逆单元用于解决模型对特征图形状的限制以及与…

线性代数求特征值和特征向量的技巧

考场时间很重要&#xff0c;所以学会方法计算挺重要。 一、求特征值&#xff1a; 大部分题目我们都可以通过矩阵行变化将矩阵的某一行的元素化简成只剩一个值&#xff0c;再按一行展开。这是我们首先应该想的。 但是考场难免会紧张&#xff0c;导致一时半会无法看出&#xf…

Java内存区域

前言 对于 Java 程序员来说&#xff0c;在虚拟机自动内存管理机制下&#xff0c;不再需要像 C/C程序开发程序员这样为每一个 new 操作去写对应的 delete/free 操作&#xff0c;不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序员把内存控制权利交给 Java 虚拟机&#xf…

【学员提问bug】小程序在onUnload里面调接口,用来记录退出的时间, 但是接口调用还没成功, 页面就关闭了。如何让接口在onUnload关闭前调用成功?

这种问题比较通用&#xff0c;并不涉及到具体方法执行障碍&#xff0c;所以&#xff0c;解决起来也不麻烦。但是新手往往不知道如何做。 在小程序中&#xff0c;如果在 onUnload 中调用 API 记录页面退出时间&#xff0c;但因为页面关闭速度较快导致请求未完成&#xff0c;可以…

“七巨头”(The Magnificent 7)科技公司财报喜忧参半看AI

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

图片分割--UNet

1.网络结构 结构可以分为两部分 左边部分是编码结构,进行特征提取 右边是解码结果,进行特征还原 2.数据集准备 import os.path from torchvision import transforms from torch.utils.data import Dataset from utils import *#数据归一化 transform transforms.Compose([tr…

Shiro安全认证技术实践

为Java后端项目添加Shiro进行身份验证&#xff0c;授权操作&#xff1a; 步骤1.引入相关依赖&#xff1a; <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.9.1</vers…