C++多线程常用方法
在 C++ 中,线程相关功能主要通过头文件提供的类和函数来实现,以下是一些常用的线程接口方法和使用技巧:
std::thread类
构造函数:
可以通过传入可调用对象(如函数指针、函数对象、lambda 表达式等)来创建一个线程实例,启动一个新线程去执行对应的任务。例如:
#include <iostream>
#include <thread>void hello() {std::cout << "Hello from thread!" << std::endl;
}int main() {std::thread t(hello); // 创建线程t并开始执行hello函数t.join(); // 等待线程t执行完毕return 0;
}
这里std::thread t(hello)就是利用函数指针hello创建线程,新线程会执行hello函数里的代码。
join方法:
用于阻塞当前线程,直到被调用的线程执行完成。比如在上面的main函数中,t.join()会让main线程暂停,等待t线程把hello函数执行完后再继续往下执行。
detach方法:
将线程分离,使得线程在后台独立运行,不再与创建它的std::thread对象关联。此后,无法再通过该std::thread对象对这个线程进行控制(比如不能再调用join了)。示例:
#include <iostream>
#include <thread>void func() {// 线程执行的函数内容std::cout << "Thread is running independently." << std::endl;
}int main() {std::thread t(func);t.detach(); // 分离线程t// 主线程继续执行其他操作,不用等待t线程结束std::cout << "Main thread continues." << std::endl;return 0;
}
线程传参
向线程函数传递参数时,需要保证参数在传递时是有效的,且在被调用函数执行期间持续有效(比如避免传引用指向临时对象等情况)。例如:
#include <iostream>
#include <thread>void print_num(int num) {std::cout << "The number is: " << num << std::endl;
}int main() {int num = 10;std::thread t(print_num, num); // 传递普通变量num作为参数t.join();return 0;
}
如果要传递类对象等更复杂的情况,要注意拷贝、移动语义等相关问题,确保参数传递的正确性。
线程 ID 获取
可以通过std::this_thread::get_id获取当前线程的线程 ID,或者通过std::thread对象的get_id成员函数获取对应的线程 ID,用于标识和区分不同线程。示例:
#include <iostream>
#include <thread>void show_thread_id() {std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;
}int main() {std::thread t(show_thread_id);std::cout << "Main thread ID: " << std::this_thread::get_id() << std::endl;t.join();return 0;
}
线程同步相关(例如互斥量等,用于解决多线程访问共享资源冲突问题)
std::mutex(互斥量):
通过lock和unlock方法对共享资源进行加锁和解锁,确保同一时刻只有一个线程能访问被保护的共享资源。例如:
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
int shared_data = 0;void increment() {for (int i = 0; i < 1000; ++i) {mtx.lock(); // 加锁shared_data++;mtx.unlock(); // 解锁}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Shared data value: " << shared_data << std::endl;return 0;
}
也可以使用std::lock_guard等 RAII(Resource Acquisition Is Initialization)机制的类来更方便、安全地管理互斥量的生命周期,自动完成加锁和解锁,如:
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
int shared_data = 0;void increment() {for (int i = 0; i < 1000; ++i) {std::lock_guard<std::mutex> guard(mtx); // 构造时加锁,析构时自动解锁shared_data++;}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Shared data value: " << shared_data << std::endl;return 0;
}
std::condition_variable(条件变量):
常和互斥量配合使用,用于线程间的同步,实现一个线程等待某个条件满足后再继续执行的功能。比如一个线程等待另一个线程修改共享资源达到某个条件后再进行后续操作,典型用法如下:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void wait_for_signal() {std::unique_lock<std::mutex> lck(mtx);cv.wait(lck, []{ return ready; }); // 等待条件满足(ready为true)std::cout << "Received signal and continue." << std::endl;
}void send_signal() {{std::lock_guard<std::mutex> lck(mtx);ready = true;}cv.notify_one(); // 通知等待在该条件变量上的一个线程
}int main() {std::thread t1(wait_for_signal);std::thread t2(send_signal);t1.join();t2.join();return 0;
}
这些就是 C++ 中线程相关的一些主要接口方法及其基本使用方式,在实际多线程编程中,往往需要综合运用它们来实现高效、正确的并发程序逻辑。
相关文章:
C++多线程常用方法
在 C 中,线程相关功能主要通过头文件提供的类和函数来实现,以下是一些常用的线程接口方法和使用技巧: std::thread类 构造函数: 可以通过传入可调用对象(如函数指针、函数对象、lambda 表达式等)来创建一…...

ubuntu+ros新手笔记(三):21讲没讲到的MoveIt2
1 安装MoveIt2 安装参照在ROS2中,通过MoveIt2控制Gazebo中的自定义机械手 安装 MoveIt2可以选择自己编译源码安装,或者直接从二进制安装。 个人建议直接二进制安装,可以省很多事。 sudo apt install ros-humble-moveitmoveit-setup-assistan…...

Android Studio创建新项目并引入第三方so外部aar库驱动NFC读写器读写IC卡
本示例使用设备:https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.52de2c1bbW3AUC&ftt&id615391857885 一、打开Android Studio,点击 File> New>New project 菜单,选择 要创建的项目模版,点击 Next 二、输入项目名称…...

window QT/C++ 与 lua交互(mingw + lua + LuaBridge + luasocket)
一、环境与准备工作 测试环境:win10 编译器:mingw QT版本:QT5.12.3 下载三种源码: LuaBridge源码:https://github.com/vinniefalco/LuaBridge LUA源码(本测试用的是5.3.5):https://www.lua.org/download.html luasocket源码:https://github.com/diegonehab/luasocket 目…...
中阳科技:量化模型驱动的智能交易革命
在金融市场飞速发展的今天,量化交易作为科技与金融的深度融合,正推动市场格局向智能化转型。中阳科技凭借先进的数据分析技术与算法研发能力,探索量化模型的升级与优化,为投资者提供高效、智能的交易解决方案。 量化交易的本质与价…...

电子应用设计方案-56:智能书柜系统方案设计
智能书柜系统方案设计 一、引言 随着数字化时代的发展和人们对知识获取的需求增加,智能书柜作为一种创新的图书管理和存储解决方案,能够提供更高效、便捷和个性化的服务。本方案旨在设计一款功能齐全、智能化程度高的智能书柜系统。 二、系统概述 1. 系…...

宠物兔需要洗澡吗?
在宠物兔的养护领域,“宠物兔需要洗澡吗” 这个问题一直备受争议。其实,这不能简单地一概而论,而要综合多方面因素考量。 兔子本身是爱干净的动物,它们日常会通过自我舔舐来打理毛发。从这个角度讲,如果兔子生活环境较…...
ubuntu升级python版本
Ubuntu升级Python版本 解压缩文件: 下载完成后,解压缩文件: tar -xf Python-3.12.0.tgz编译并安装: 进入解压后的目录,然后配置和安装Python: codecd Python-3.12.0 ./configure --enable-optimizations ma…...

《Time Ghost》的制作:使用 DOTS ECS 制作更为复杂的大型环境
*基于 Unity 6 引擎制作的 demo 《Time Ghost》 开始《Time Ghost》项目时的目标之一是提升在 Unity 中构建大型户外环境的构建标准。为了实现这一目标,我们要有处理更为复杂的场景的能力、有足够的工具支持,同时它对引擎的核心图形、光照、后处理、渲染…...
详细描述一下 Elasticsearch 更新和删除文档的过程。
1、删 除 和 更 新 也 都 是 写 操 作 , 但 是 Elasticsearch 中的 文 档 是 不 可 变 的 , 因 此 不 能被 删 除 或 者 改 动 以 展 示 其 变 更 ; 2、磁盘 上 的 每 个 段 都 有 一 个 相 应 的 .del 文件 。当删 除 请 求 发 送 后 &#…...

OpenCV与Qt5开发卡尺找圆工具
文章目录 前言一、卡尺原理二、1D边缘提取三、圆拟合四、软件实现结束语 基于OpenCV与Qt5构建卡尺找圆工具 前言 博主近期基于海康Vision Master4.0做了一个工业视觉工程项目,其中就使用到了海康VM的找圆工具,然后博主根据其中的技术原理,也…...
【网络安全】Web Timing 和竞争条件攻击:揭开隐藏的攻击面
Web Timing 和竞争条件攻击:揭开隐藏的攻击面 在传统的 Web 应用中,漏洞的发现和利用通常相对容易理解。如果代码存在问题,我们可以通过发送特定输入来强制 Web 应用执行非预期的操作。这种情况下,输入和输出之间往往有直接关系&…...

分立器件---运算放大器关键参数
运算放大器 关键参数 1、供电电压:有单电源电压、双电源电压,双电源电压尽量两个电源都接。如图LM358B,供电电压可以是20V或者是40V和GND。 2、输入偏置电流IB:当运放输出直流电压为零时,运放两个输入端流进或者流出直流电流的平均值。同向输入端电流IB+与反向输入端电流…...

Stable Diffusion Controlnet常用控制类型解析与实战课程 4
本节内容,是stable diffusion Controlnet常用控制类型解析与实战的第四节课程。上节课程,我们陆续讲解了几个与图像风格约束相关的控制类型,本节课程我们再学习一些实用价值较高的控制类型,看一看他们提供了哪些控制思路。 一&…...
Linux 本地编译安装 gcc9
这里演示非sudo权限的本地linux 用户安装 gcc9 下载源代码: 可以从GCC官方网站或其镜像站点下载GCC 9的源代码压缩包。使用wget或curl命令,这通常不需要额外权限 wget https://ftp.gnu.org/gnu/gcc/gcc-9.5.0/gcc-9.5.0.tar.gz tar -xf gcc-9.5.0.tar…...
SpringBoot 自定义事件
在Spring Boot中,自定义事件和监听器是一种强大的机制,允许你在应用程序的不同部分之间进行解耦通信。你可以定义自定义事件,并在需要的时候发布这些事件,同时让其他组件通过监听器来响应这些事件。 以下是如何在Spring Boot中创…...
unity shader中的逐像素光源和逐顶点光源
在Unity Shader中,逐像素光源和逐顶点光源是两种不同的光照计算方法,它们之间存在显著的区别。 一、基本原理 逐顶点光源:这种方法在顶点着色器中计算每个顶点的光照值。然后,在片段着色器中,通过插值算法将这些顶点…...

MongoDB-副本集
一、什么是 MongoDB 副本集? 1.副本集的定义 MongoDB 的副本集(Replica Set)是一组 MongoDB 服务器实例,它们存储同一数据集的副本,确保数据的高可用性和可靠性。副本集中的每个节点都有相同的数据副本,但…...
【图像处理lec7】图像恢复、去噪
目录 一、图像退化与恢复概述 二、图像退化中的噪声模型 1、使用 imnoise 函数添加噪声 (1)imnoise 函数的概述 (2)函数语法 (3)支持的噪声类型与具体语法 (4)噪声类型的详细…...
C# 连接ClickHouse 数据库
在 C# 中连接 ClickHouse 数据库,您可以使用 ClickHouse.Client 库。这个库提供了对 ClickHouse 数据库的高效访问。以下是详细的步骤指南,帮助您在 C# 项目中连接和操作 ClickHouse 数据库。 1. 安装 ClickHouse.Client 包 首先,您需要在您…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...

Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...