C++ 之多线程相关总结
C++ 之多线程相关总结
1.多线程相关基础知识
1.1 线程的创建和管理
1. std::thread 类:
用于创建和管理线程。通过将可调用对象(如函数、函数对象、lambda 表达式)作为参数传递给 std::thread 的构造函数,可以创建一个新的线程。
join()方法会阻塞当前线程,直到被调用的线程执行完毕。如果不调用join()或detach(),程序会在std::thread对象析构时终止程序,因为会调用std::terminate()。detach()方法允许线程独立运行,与主线程分离,不再被std::thread对象管理,它会继续在后台执行直至完成或程序结束。
#include <iostream>
#include <thread>void threadFunction() {std::cout << "Thread function running." << std::endl;
}int main() {std::thread t(threadFunction); // 创建一个新的线程,执行 threadFunctiont.join(); // 等待线程结束return 0;
}
2. 线程函数:
可以是普通函数、成员函数、函数对象或 lambda 表达式。
#include <iostream>
#include <thread>class MyClass {
public:void memberFunction() {std::cout << "Member function running in thread." << std::endl;}
};int main() {MyClass obj;std::thread t(&MyClass::memberFunction, &obj); // 调用成员函数t.join();return 0;
}
1.2 线程同步
1.互斥量(Mutex):
- std::mutex 提供了基本的互斥机制,用于保护共享数据,防止多个线程同时访问。
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;void printMessage(const std::string& message) {std::lock_guard<std::mutex> lock(mtx); // 自动加锁和解锁std::cout << message << std::endl;
}int main() {std::thread t1(printMessage, "Hello from thread 1");std::thread t2(printMessage, "Hello from thread 2");t1.join();t2.join();return 0;
}
std::lock_guard是一个 RAII 类,在构造时自动锁定互斥量,在析构时自动解锁,确保正确的锁定和解锁操作。std::unique_lock提供了更灵活的锁定方式,可以手动加锁、解锁,支持延迟锁定和所有权转移。
2.条件变量(Condition Variables):
- std::condition_variable 允许线程等待某些条件的发生。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>std::mutex mtx;
std::condition_variable cv;
std::queue<int> dataQueue;void producer() {for (int i = 0; i < 10; ++i) {std::this_thread::sleep_for(std::chrono::milliseconds(100));std::unique_lock<std::mutex> lock(mtx);dataQueue.push(i);std::cout << "Produced: " << i << std::endl;cv.notify_one(); // 通知一个等待的线程}
}void consumer() {while (true) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return!dataQueue.empty(); }); // 等待条件满足int data = dataQueue.front();dataQueue.pop();lock.unlock();std::cout << "Consumed: " << data << std::endl;if (data == 9) break;}
}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;
}
cv.wait()会释放锁并等待条件变量被通知,一旦收到通知,它会重新获取锁。
3. 原子操作
std::atomic模板类提供了原子操作,确保操作的不可分割性,避免数据竞争。
#include <iostream>
#include <thread>
#include <atomic>std::atomic<int> counter(0);void increment() {for (int i = 0; i < 1000; ++i) {++counter;}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Counter value: " << counter << std::endl;return 0;
}
1.3 线程间通信
1.共享数据:
- 多个线程可以通过共享数据进行通信,但需要使用互斥量或其他同步机制来保护数据。
- 避免死锁,如避免多个线程以不同顺序获取多个锁。
2.消息传递:
- 使用
std::promise和std::future可以实现线程间的单向消息传递。
#include <iostream>
#include <thread>
#include <future>int factorial(int n) {int result = 1;for (int i = 1; i <= n; ++i) {result *= i;}return result;
}int main() {std::promise<int> prom;std::future<int> fut = prom.get_future();std::thread t([&prom]() {int result = factorial(5);prom.set_value(result);});std::cout << "Factorial result: " << fut.get() << std::endl;t.join();return 0;
}
1.4 高级线程工具
1. std::async 和 std::future:
std::async可以异步执行函数,并返回一个std::future对象。
#include <iostream>
#include <future>int add(int a, int b) {return a + b;
}int main() {std::future<int> result = std::async(std::launch::async, add, 3, 4);std::cout << "Sum: " << result.get() << std::endl;return 0;
}
std::launch::async表示函数会在另一个线程中立即执行,std::launch::deferred表示延迟执行,直到调用get()时才在调用线程中执行。
2. std::packaged_task:
- 包装可调用对象,允许将其作为任务传递,并通过
std::future获取结果。
#include <iostream>
#include <thread>
#include <future>int main() {std::packaged_task<int(int, int)> task(add);std::future<int> result = task.get_future();std::thread t(std::move(task), 3, 4);std::cout << "Sum: " << result.get() << std::endl;t.join();return 0;
}
2. 线程的使用:创建及管理
1.类内创建线程
- 可以通过成员函数或者析构函数初始化或者创建线程,通过析构函数关闭/销毁线程
#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>class ThreadedClass {
private:std::thread workerThread;std::atomic<bool> stopFlag;// 线程函数void workerFunction() {while (!stopFlag) {std::cout << "Thread is running..." << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}std::cout << "Thread is stopping..." << std::endl;}
public:ThreadedClass() : stopFlag(false) {// 启动线程workerThread = std::thread(&ThreadedClass::workerFunction, this);}~ThreadedClass() {// 设置停止标志stopFlag = true;if (workerThread.joinable()) {// 等待线程结束workerThread.join();}}
};int main() {ThreadedClass obj;// 让程序运行一段时间,以便观察线程的行为std::this_thread::sleep_for(std::chrono::seconds(5));return 0;
}
2. 函数内部创建线程
- 单独执行某个函数或者某个类的成员函数
#include <iostream>
#include <thread>
#include <chrono>class MyClass {
public:// 类中的函数,将在新线程中执行void classFunction() {for (int i = 0; i < 5; ++i) {std::cout << "Class function running, iteration: " << i << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}}
};// 主函数,在其中创建线程执行类的函数
void mainFunction() {std::cout << "Main function starts." << std::endl;MyClass obj;// 创建一个新线程执行类的成员函数std::thread t(&MyClass::classFunction, &obj);// 主线程继续执行自己的任务for (int i = 0; i < 3; ++i) {std::cout << "Main function running, iteration: " << i << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}// 等待新线程执行完毕t.join();std::cout << "Main function ends." << std::endl;
}// 函数将在新线程中执行
void newThreadFunction() {for (int i = 0; i < 5; ++i) {std::cout << "New thread: " << i << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}
}int main() {mainFunction();//or// 创建一个新线程std::thread newThread(newThreadFunction);// 主线程继续执行自己的任务for (int i = 0; i < 3; ++i) {std::cout << "Main thread: " << i << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}// 等待新线程执行完成newThread.join();return 0;
}
----更新中。。。。。
相关文章:
C++ 之多线程相关总结
C 之多线程相关总结 1.多线程相关基础知识 1.1 线程的创建和管理 1. std::thread 类: 用于创建和管理线程。通过将可调用对象(如函数、函数对象、lambda 表达式)作为参数传递给 std::thread 的构造函数,可以创建一个新的线程。…...
EF Core全局查询筛选器
目录 概述 用法 添加全局查询筛选器 禁用全局查询筛选器 概述 全局查询筛选器:EF Core 会自动将这个查询筛选器应用于涉及这个实体类型的所有 LINQ 查询。 场景:软删除、多租户。 什么是软删除? 逻辑删除,并不是真正地从数…...
【开源免费】基于SpringBoot+Vue.JS欢迪迈手机商城(JAVA毕业设计)
本文项目编号 T 141 ,文末自助获取源码 \color{red}{T141,文末自助获取源码} T141,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...
Objective-C语言的数据库交互
Objective-C语言的数据库交互 引言 在现代应用程序开发过程中,数据库在数据存储和管理方面起着至关重要的作用。对于iOS应用开发者而言,掌握如何在Objective-C中与数据库交互显得尤为重要。本文将全面探讨Objective-C的数据库交互,包括SQLi…...
基于 Spring Boot 和 Vue.js 的全栈购物平台开发实践
在现代 Web 开发中,前后端分离的架构已经成为主流。本文将分享如何使用 Spring Boot 和 Vue.js构建一个全栈购物平台,涵盖从后端 API 开发到前端页面实现的完整流程。 1. 技术栈介绍 后端技术栈 JDK 1.8:稳定且广泛使用的 Java 版本。 Spring…...
笔记(数据运营方向)
以下是一些在工作过程中的小笔记,写的比较杂乱,后续再进行分类~ 1、掌握sql窗口函数 窗口函数又名开窗函数,属于分析函数的一种。用于解决复杂报表统计需求的功能强大的函数。窗口函数用于计算基于组的某种聚合值,它和聚合函数的…...
qt vs ios开发应用环境搭建和上架商店的记录
qt 下载链接如下 https://download.qt.io/new_archive/qt/5.14/5.14.2/qt-opensource-mac-x64-5.14.2.dmg 安装选项全勾选就行,这里特别说明下qt5.14.2/qml qt5.14.2对qml支持还算成熟,但很多特性还得qt6才行,这里用qt5.14.2主要是考虑到服…...
[cg] glDrawBuffers MRT的应用
glDrawBuffers 是 OpenGL 中的一个函数,用于指定渲染结果输出到哪些颜色缓冲区。它通常在多渲染目标(MRT, Multiple Render Targets)中使用,允许一个渲染操作同时将结果输出到多个颜色缓冲区,而不是默认情况下的单个颜…...
IO模型与NIO基础二
抽象基类之二 FilterInputStream FilterInputStream 的作用是用来“封装其它的输入流,并为它们提供额外的功能”。 它的常用的子类有BufferedInputStream和DataInputStream。 (1) BufferedInputStream的作用就是为“输入流提供缓冲功能,以及mark()和res…...
【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)
单例模式 作用:单例模式的核心是保证一个类只有一个实例,并且提供一个访问实例的全局访问点。 实现方式优缺点饿汉式线程安全,调用效率高 ,但是不能延迟加载懒汉式线程安全,调用效率不高,能延迟加载双重检…...
T-SQL语言的数据库交互
T-SQL语言的数据库交互 引言 随着信息技术的不断发展,数据库在各个行业中扮演着越来越重要的角色。数据库的有效管理和优化对于企业的数据安全、效率提升和决策支持至关重要。T-SQL(Transact-SQL)作为微软SQL Server的重要扩展语言…...
【Linux系统】Ext系列磁盘文件系统二:引入文件系统(续篇)
inode 和 block 的映射 该博文中有详细解释:【Linux系统】inode 和 block 的映射原理 目录与文件名 这里有几个问题: 问题一: 我们访问文件,都是用的文件名,没用过 inode 号啊? 之前总是说可以通过一个…...
慧集通(DataLinkX)iPaaS集成平台-业务建模之域
通过左侧导航菜单〖业务建模〗→〖域〗,进入该界面;在该界面可以查看到系统中已存在的域列表。 新建域 在慧集通平台中进入【业务建模】的【域】页面,点击【新建】按钮进入新建页面;输入编码,名称、模块以及对应数据类…...
【机器学习实战】kaggle 欺诈检测---使用生成对抗网络(GAN)解决欺诈数据中正负样本极度不平衡问题
【机器学习实战】kaggle 欺诈检测---如何解决欺诈数据中正负样本极度不平衡问题https://blog.csdn.net/2302_79308082/article/details/145177242 本篇文章是基于上次文章中提到的对抗生成网络,通过对抗生成网络生成少数类样本,平衡欺诈数据中正类样本极…...
android wifi framework与wpa_supplicant的交互
android frmework直接与wpa_supplicant进行交互,使用aidl或者hidl 二、事件 framework注册事件的地方: packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java class SupplicantStaIfaceCallbackImpl exte…...
初学stm32 --- flash模仿eeprom
目录 STM32内部FLASH简介 内部FLASH构成(F1) FLASH读写过程(F1) 闪存的读取 闪存的写入 内部FLASH构成(F4 / F7 / H7) FLASH读写过程(F4 / F7 / H7) 闪存的读取 闪存的写入 …...
使用C语言实现栈的插入、删除和排序操作
栈是一种后进先出(LIFO, Last In First Out)的数据结构,这意味着最后插入的元素最先被删除。在C语言中,我们可以通过数组或链表来实现栈。本文将使用数组来实现一个简单的栈,并提供插入(push)、删除(pop)以及排序(这里采用一种简单的排序方法,例如冒泡排序)的操作示…...
C语言程序环境和预处理详解
本章重点: 程序的翻译环境 程序的执行环境 详解:C语言程序的编译链接 预定义符号介绍 预处理指令 #define 宏和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令 #include 预处理指令 #undef 条件编译 程序的翻译环境和执行环…...
基于机器学习随机森林算法的个人职业预测研究
1.背景调研 随着信息技术的飞速发展,特别是大数据和云计算技术的广泛应用,各行各业都积累了大量的数据。这些数据中蕴含着丰富的信息和模式,为利用机器学习进行职业预测提供了可能。机器学习算法的不断进步,如深度学习、强化学习等…...
三种文本相似计算方法:规则、向量与大模型裁判
文本相似计算 项目背景 目前有众多工作需要评估字符串之间的相似(相关)程度: 比如,RAG 智能问答系统文本召回阶段需要计算用户文本与文本库内文本的相似分数,返回前TopK个候选文本。 在评估大模型生成的文本阶段,也需要评估…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
