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++ 中线程相关的一些主要接口方法及其基本使用方式,在实际多线程编程中,往往需要综合运用它们来实现高效、正确的并发程序逻辑。

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

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

相关文章

up主亲测,ToDesk/青椒云/顺网云这三款云电脑玩转AIGC场景

文章目录 1. 前言2. 云电脑性能分析3. 基础硬件数据3.1 硬件配置3.2 AI 评测跑分 4. 云电脑 AIGC 上手实测4.1 ToDesk4.1.1 AIGC 技术集成情况4.1.2 界面及功能4.1.3 项目部署4.1.4 黑神话悟空 AI 换脸4.1.6 AIGC 文生图体验 4.2 青椒云4.2.1 AIGC 技术集成情况4.2.2 界面及功能…

C++(十八)

前言&#xff1a; 本文依据上一篇&#xff0c;继续对C中的函数进行学习。 一&#xff0c;内联函数。 再执行函数代码时&#xff0c;比不使用函数花费了更多时间&#xff0c;因为总结步骤&#xff0c;传递参数和返回值都很花费时间。 因此&#xff0c;在调试小型函数时&…

功能篇:JAVA后端实现跨域配置

在Java后端实现跨域配置&#xff08;CORS&#xff0c;Cross-Origin Resource Sharing&#xff09;有多种方法&#xff0c;具体取决于你使用的框架。如果你使用的是Spring Boot或Spring MVC&#xff0c;可以通过以下几种方式来配置CORS。 ### 方法一&#xff1a;全局配置 对于所…

数独游戏app制作拆解(之一)——功能介绍

android studio版本&#xff1a;2023.3.1 例程名称&#xff1a;shudu666 前阵子作了一个EXCEL版的数独&#xff0c;再早之前就想作这个数独app,但一直没动手&#xff0c;一方面懒&#xff0c;另一方面我把自己绕到坑里了&#xff0c;之前做的是一解数独的app,那个是有点难&am…

Spring注解篇:@Configuration详解

前言 在Spring框架中&#xff0c;Configuration注解是实现Java配置的核心。它允许开发者以编程的方式定义Bean的创建过程&#xff0c;而不是使用XML文件。这种基于注解的配置方式&#xff0c;不仅简化了配置的复杂性&#xff0c;还提高了代码的可读性和可维护性。 摘要 本文…

通过一个例子学习回溯算法:从方法论到实际应用

回溯算法&#xff1a;从方法论到实际应用 回溯算法&#xff08;Backtracking&#xff09;是一种通过穷举法寻找问题所有解的算法&#xff0c;它的核心思想是逐步构建解空间树&#xff0c;在每个步骤中判断当前解是否合法。如果不合法&#xff0c;就“回溯”到上一步&#xff0…

Python随机抽取Excel数据并在处理后整合为一个文件

本文介绍基于Python语言&#xff0c;针对一个文件夹下大量的Excel表格文件&#xff0c;基于其中每一个文件&#xff0c;随机从其中选取一部分数据&#xff0c;并将全部文件中随机获取的数据合并为一个新的Excel表格文件的方法。 首先&#xff0c;我们来明确一下本文的具体需求。…

构建树莓派温湿度监测系统:从硬件到软件的完整指南

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

28. Three.js案例-创建圆角矩形并进行拉伸

28. Three.js案例-创建圆角矩形并进行拉伸 实现效果 知识点 WebGLRenderer (WebGL渲染器) WebGLRenderer 是 Three.js 中用于渲染 3D 场景的主要渲染器。 构造器 WebGLRenderer( parameters : Object ) 参数类型描述parametersObject渲染器的配置参数&#xff0c;可选。 …

开源Java快速自测工具,可以调用系统内任意一个方法

java快速测试框架&#xff0c;可以调到系统内任意一个方法&#xff0c;告别写单测和controller的困扰。 开源地址&#xff1a;https://gitee.com/missyouch/Easy-JTest 我们在开发时很多时候想要测试下自己的代码&#xff0c;特别是service层或者是更底层的代码&#xff0c;就…

004 QT常用控件Qwidget_上

文章目录 前言控件概述QWidgetenable属性geometry属性windowTitle属性windowlcon属性 小结 前言 本文将会向你介绍常用的Qwidget属性 控件概述 Widget 是 Qt 中的核心概念. 英文原义是 “⼩部件”, 我们此处把它翻译为 “控件” . 控件是构成⼀个图形化界面的基本要素. QWi…

Android 好的开源库

1. 权限请求框架 GitHub - getActivity/XXPermissions: Android 权限请求框架&#xff0c;已适配 Android 14 2. 下载框架 GitHub - lingochamp/okdownload: A Reliable, Flexible, Fast and Powerful download engine.

Flash语音芯片相比OTP语音芯片的优势

Flash语音芯片和OTP语音芯片是两种常见的语音解决方案&#xff0c;在各自的应用领域中发挥着重要作用。本文‌将介绍Flash语音芯片相比OTP(One-Time Programmable)语音芯片的显著优势‌。 1‌.可重复擦写‌&#xff1a;Flash语音芯片的最大特点是支持多次编程和擦除&#xff0c…

Android命令行工具--dumpsys

dumpsys 是一种在 Android 设备上运行的工具&#xff0c;可提供有关系统服务的信息。可以使用 Android 调试桥 (adb) 从命令行调用 dumpsys&#xff0c;获取在连接的设备上运行的所有系统服务的诊断输出。 此输出通常比您想要的更详细&#xff0c;因此请使用此页面上的命令行选…

【深度学习】深刻理解Swin Transformer

Swin Transformer 是一种基于 Transformer 的视觉模型&#xff0c;由 Microsoft 研究团队提出&#xff0c;旨在解决传统 Transformer 模型在计算机视觉任务中的高计算复杂度问题。其全称是 Shifted Window Transformer&#xff0c;通过引入分层架构和滑动窗口机制&#xff0c;S…

从零开始学习 sg200x 多核开发之 sophpi 编译生成 fip.bin 流程梳理

本文主要介绍 sophpi 编译生成 fip.bin 流程。 1、编译前准备 sophpi 的基本编译流程如下&#xff1a; $ source build/cvisetup.sh $ defconfig sg2002_wevb_riscv64_sd $ clean_all $ build_all $ pack_burn_image注&#xff1a; 需要在 bash 下运行clean_all 非必要可以不…

mysql客户端命令

目录 结束符 ; \g \G 中断输入 ctrl c 查看命令列表 help ? (\?) connect (\r) status (\s) delimiter (\d) exit (\q) quit (\q) tee (\T) ​编辑 notee (\t) prompt (\R) source (\.) system (\!) ​编辑 use (\u) help contents 结束符 ; \g \G 当我…

scala隐式函数

1 定义 通常我们所说的隐式函数也称为 隐式转换&#xff0c;是使用 implicit 修饰的函数 作用&#xff1a; 可以通过一个隐式函数将一种类型转变为另一种类型 隐式转换有两种应用场景&#xff1a; 类型转换&#xff0c;隐式转换为期望类型 类型增强 2 示例 ①&#xff1a;类…

Tomcat原理(4)——尝试手动Servlet的实现

目录 一、什么是Servlet 1.servlet的定义 2.servlet的结构 二、实现servlet的流程图 三、具体实现代码 1、server 2.实体类request&response 3.HttpServlet抽象类 4.再定义三个servlet进行测试 Tomcat原理&#xff08;3&#xff09;——静&动态资源以及运行项…

Node.js内置模块

1.内置模块 Node.js的中文网参考手册:https://nodejs.cn//api 帮助文档 API文档:查看对应的模块,左边是模块,右边是模块的成员 源码:https://github.com/nodejs/node/tree/main/lib 查看 例如: http.js 创建web服务器的模块 -->进入源码中,搜索…