<C++学习>C++ std 多线程教程
C++ std 多线程教程
理解多线程的概念
多线程是一种并发编程技术,它允许程序同时运行多个任务。每个线程共享同一进程的资源(如内存),但拥有独立的执行路径。多线程编程在现代 C++ 中变得更加便捷和安全,标准库提供了强大的多线程支持,包括线程创建、同步和管理。
多线程的优点
- 提高性能:充分利用多核 CPU 的并行计算能力。
- 异步操作:后台任务(如文件处理、网络通信)可以在不阻塞主线程的情况下运行。
- 简化复杂任务:将复杂任务分解为多个线程独立处理。
C++ 提供的多线程支持
C++11 开始标准库新增了 <thread> 模块,用于线程管理,并提供同步机制(如互斥锁、条件变量)。
1. C++ 多线程基础
1.1 创建线程
通过 std::thread 创建线程。线程可以执行:
- 函数。
- Lambda 表达式。
- 成员函数。
示例
#include <iostream>
#include <thread>void printMessage() {std::cout << "Hello from thread!" << std::endl;
}int main() {std::thread t(printMessage); // 创建线程 tt.join(); // 等待线程 t 执行完毕return 0;
}
1.2 线程的生命周期
- 创建:通过
std::thread创建新线程。 - 加入:
join():主线程等待子线程完成。detach():分离线程,子线程独立运行。
- 结束:线程完成任务或被终止。
示例:detach 和 join
#include <iostream>
#include <thread>void detachedThread() {std::cout << "Detached thread running..." << std::endl;
}void joinedThread() {std::cout << "Joined thread running..." << std::endl;
}int main() {std::thread t1(detachedThread);t1.detach(); // 分离线程,主线程不再管理它std::thread t2(joinedThread);t2.join(); // 主线程等待 t2 完成std::cout << "Main thread finished." << std::endl;return 0;
}
1.3 Lambda 表达式作为线程函数
示例
#include <iostream>
#include <thread>int main() {std::thread t([] {std::cout << "Hello from Lambda!" << std::endl;});t.join();return 0;
}
1.4 传递参数到线程
通过 std::thread 构造函数将参数传递给线程函数。
示例
#include <iostream>
#include <thread>void printNumbers(int n, const std::string& message) {for (int i = 0; i < n; i++) {std::cout << message << " " << i << std::endl;}
}int main() {std::thread t(printNumbers, 5, "Count"); // 传递参数 5 和 "Count"t.join();return 0;
}
2. 线程同步
多线程共享资源时,可能会导致数据竞争(race condition)。C++ 提供了多种同步机制来解决这些问题。
2.1 互斥锁(std::mutex)
示例:保护共享资源
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx; // 定义一个互斥锁
int counter = 0;void increment() {for (int i = 0; i < 100; i++) {std::lock_guard<std::mutex> lock(mtx); // 自动加锁和解锁counter++;}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Final counter value: " << counter << std::endl;return 0;
}
2.2 条件变量(std::condition_variable)
条件变量用于线程间通信和同步。
示例:生产者-消费者模型
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>std::queue<int> q;
std::mutex mtx;
std::condition_variable cv;void producer() {for (int i = 0; i < 10; i++) {std::unique_lock<std::mutex> lock(mtx);q.push(i);std::cout << "Produced: " << i << std::endl;cv.notify_one(); // 通知消费者}
}void consumer() {for (int i = 0; i < 10; i++) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [] { return !q.empty(); }); // 等待队列非空int item = q.front();q.pop();std::cout << "Consumed: " << item << std::endl;}
}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;
}
3. 多线程的Linux Demo
以下示例演示了如何在 Linux 环境下编写一个多线程程序,该程序计算数组的部分和,并最终输出总和。
完整代码
#include <iostream>
#include <thread>
#include <vector>
#include <numeric>
#include <functional>void partialSum(const std::vector<int>& data, int start, int end, int& result) {result = std::accumulate(data.begin() + start, data.begin() + end, 0);std::cout << "Partial sum [" << start << ", " << end << ") = " << result << std::endl;
}int main() {const int size = 100;std::vector<int> data(size);std::iota(data.begin(), data.end(), 1); // 初始化数组 [1, 2, ..., 100]int numThreads = 4;int blockSize = size / numThreads;std::vector<std::thread> threads;std::vector<int> results(numThreads);// 启动线程for (int i = 0; i < numThreads; i++) {int start = i * blockSize;int end = (i == numThreads - 1) ? size : start + blockSize;threads.emplace_back(partialSum, std::cref(data), start, end, std::ref(results[i]));}// 等待线程完成for (auto& t : threads) {t.join();}// 计算总和int totalSum = std::accumulate(results.begin(), results.end(), 0);std::cout << "Total sum: " << totalSum << std::endl;return 0;
}
运行示例
在 Linux 环境中编译和运行:
g++ -std=c++11 -pthread -o multithreading_demo multithreading_demo.cpp
./multithreading_demo
结果示例
Partial sum [0, 25) = 325
Partial sum [25, 50) = 950
Partial sum [50, 75) = 1575
Partial sum [75, 100) = 2200
Total sum: 5050
学习建议
- 理解线程的生命周期:掌握线程的创建、管理和结束。
- 同步机制:熟悉
std::mutex和std::condition_variable的使用。 - 多线程调试:在 Linux 中使用工具(如
gdb)调试多线程程序。
通过这些内容,你可以编写高效的 C++ 多线程程序,并在实际项目中灵活运用!
相关文章:
<C++学习>C++ std 多线程教程
C std 多线程教程 理解多线程的概念 多线程是一种并发编程技术,它允许程序同时运行多个任务。每个线程共享同一进程的资源(如内存),但拥有独立的执行路径。多线程编程在现代 C 中变得更加便捷和安全,标准库提供了强大…...
用 Python 自动化处理日常任务
💖 欢迎来到我的博客! 非常高兴能在这里与您相遇。在这里,您不仅能获得有趣的技术分享,还能感受到轻松愉快的氛围。无论您是编程新手,还是资深开发者,都能在这里找到属于您的知识宝藏,学习和成长…...
《深入浅出HTTPS》读书笔记(28):DSA数字签名
《深入浅出HTTPS》读书笔记(28):DSA数字签名 对称加密算法有很多算法,标准算法是RSA机密算法,数字签名技术也有一个标准DSS(Digital Signature Standard),其标准…...
type 属性的用途和实现方式(图标,表单,数据可视化,自定义组件)
1.图标类型 <uni-icon>组件中,type可以用来指定图标的不同样式。 <uni-icons type"circle" size"30" color"#007aff"></uni-icons> //表示圆形 <uni-icons type"square" size"30" co…...
PSINS工具箱学习(四)捷联惯导更新算法
原始 Markdown文档、Visio流程图、XMind思维导图见:https://github.com/LiZhengXiao99/Navigation-Learning 文章目录 一、捷联惯导更新1、insinit():初始化 ins 结构体2、ethupdate():地球自转角速度和牵连角速度更新3、insupdate():捷联惯导更新1. 速度更新2. 位置更新3.…...
P1Linux和Docker常用终端命令:保姆级图文详解
文章目录 前言1、Docker 常用命令1.1、镜像管理1.2、容器管理1.3、网络管理1.4、数据卷管理1.5、监控和性能管理 2、Linux 常用命令分类2.1、文件和目录管理2.2、用户管理2.3、系统监控和性能2.4、软件包管理2.5、网络管理 前言 亲爱的家人们,创作很不容易…...
Windows重装后NI板卡LabVIEW恢复正常
在重新安装Windows系统后,NI(National Instruments)板卡能够恢复正常工作,通常是由于操作系统的重新配置解决了之前存在的硬件驱动、兼容性或配置问题。操作系统重装后,系统重新加载驱动程序、清理了潜在的冲突或损坏的…...
深度解析统计学四大分布:Z、卡方、t 与 F 的关联与应用
统计学关键分布:Z、卡方、t、F 的关系探秘与应用指南 A/B实验系列相关文章(置顶) 1. A/B实验之置信检验(一):如何避免误判和漏报 2. A/B实验之置信检验(二):置信检验精要…...
zkServer.sh脚本
Apache ZooKeeper 几种常见的方法: 一、使用 zkServer.sh 脚本: 最常见的启动 ZooKeeper 的方式是使用提供的 zkServer.sh 脚本。此脚本可用于管理 ZooKeeper 进程。以下是一些示例命令: 1. 在前台启动 ZooKeeper: ./zkServer.s…...
CV(10)--目标检测
前言 仅记录学习过程,有问题欢迎讨论 目标检测 object detection,就是在给定的图片中精确找到物体所在位置,并标注出物体的类别;输出的是分类类别label物体的外框(x, y, width, height)。 目标检测算法:…...
UML系列之Rational Rose笔记七:状态图
一、新建状态图 依旧是新建statechart diagram; 二、工作台介绍 接着就是一个状态的开始:开始黑点依旧可以从左边进行拖动放置: 这就是状态的开始,和活动图泳道图是一样的;只能有一个开始,但是可以有多个…...
C++单例模式的设计
单例模式(Singleton Pattern)是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来访问该实例。在C中,单例模式通常用于管理全局资源或共享状态。 以下是C中实现单例模式的几种常见方式: 懒…...
基于springboot的自习室预订系统
作者:学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等 文末获取“源码数据库万字文档PPT”,支持远程部署调试、运行安装。 项目包含: 完整源码数据库功能演示视频万字文档PPT 项目编码࿱…...
shell笔记
1.使用 ls -l 及 find 查找某个或者多个目录文件数量时 单个目录: find 目录 -type f|wc -l与 ls -l 目录|grep -v total|wc -l 一致 多个目录:如上结果不一致,因为 ls -l 在算多目录时,会将多目录及空格打出算作额外行 find 更精…...
《鸿蒙Next微内核:解锁人工智能决策树并行计算的加速密码》
在当今人工智能飞速发展的时代,提升运算速度是推动其进步的关键。鸿蒙Next以其独特的微内核特性,为设计决策树的并行计算框架提供了新的思路和契机。 鸿蒙Next微内核特性概述 鸿蒙Next的微内核架构将核心功能模块化,仅保留进程管理、内存管…...
AI刷题-最大矩形面积问题、小M的数组变换
目录 一、最大矩形面积问题 问题描述 输入格式 输出格式 输入样例 输出样例 数据范围 解题思路: 问题理解 数据结构选择 算法步骤 最终代码: 运行结果: 二、小M的数组变换 问题描述 测试样例 解题思路: 问题…...
Redis集群部署详解:主从复制、Sentinel哨兵模式与Cluster集群的工作原理与配置
集群部署形式 1、主从复制1.1 工作机制1.2 配置实现1.3 优缺点1.4 部署形式1.5 主从复制优化 2、Sentinel 哨兵模式2.1 工作机制2.2 配置实现2.3 优缺点2.4 哨兵机制选举流程2.5 脑裂问题解决方案 3、Redis Cluster3.1 工作机制3.2 配置实现3.3 优缺点3.4 故障转移3.5 哈希槽为…...
LeetCode热题100(三十四) —— 23.合并K个升序链表
LeetCode热题100(三十四) —— 23.合并K个升序链表 题目描述代码实现思路一:选择排序(199ms)思路二:归并排序(2ms) 思路解析 你好,我是杨十一,一名热爱健身的程序员在Coding的征程中,不断探索与…...
kalilinux - 目录扫描之dirsearch
情景导入 先简单介绍一下dirsearch有啥用。 假如你现在访问一个网站,例如https://www.example.com/ 它是一个电商平台或者其他功能性质的平台。 站在开发者的角度上思考,我们只指导https://www.example.com/ 但不知道它下面有什么文件,文…...
浅谈云计算04 | 云基础设施机制
探秘云基础设施机制:云计算的基石 一、云基础设施 —— 云计算的根基二、核心机制之网络:连接云的桥梁(一)虚拟网络边界ÿ…...
智能检索新范式,让AIAgent自主决策,提升RAG效率100%!
市面上的 RAG 系统,不管叫什么名字,本质上只有两种做法: 第一种,一次性检索。把用户的 query 向量化,从语料库里捞出 Top-K 个文档片段,拼成一个大 prompt 塞给模型。GraphRAG、HippoRAG、LightRAG 都属于…...
户外实用|艾迪欧 R6000 测评 —— 户外 / 自驾 / 露营的通讯好搭档
户外出行,通讯工具的核心是稳定、清晰、耐用、续航久、功能全。艾迪欧 R6000 作为一款兼顾专业与户外的 DMR 对讲机,全频段覆盖、双模通讯、自定义功能、长续航,完美适配自驾、露营、登山、越野等户外场景,是户外爱好者的靠谱通讯…...
金融合规审核为何人力堆积却仍漏洞百出?2026年RegTech演进与Agent全链路闭环解决方案
在2026年的金融监管环境下,合规审核已不再是简单的“查漏补缺”,而是演变为一场高强度的算力与逻辑博弈。尽管金融机构在合规成本上的投入逐年攀升,甚至不惜以“人海战术”填补流程断点,但监管罚单的数额与频率却并未显著下降。这…...
告别混乱绑定!在UE5 GAS中优雅管理技能输入(基于GameplayTag)
告别混乱绑定!在UE5 GAS中优雅管理技能输入(基于GameplayTag)当你的UE5 RPG项目发展到中期,技能数量从十几个膨胀到几十个时,最痛苦的莫过于发现InputAction绑定已经变成一团乱麻。每次新增技能都要修改输入绑定逻辑&a…...
终极Chrome画中画扩展:如何在浏览器中实现高效视频多任务处理
终极Chrome画中画扩展:如何在浏览器中实现高效视频多任务处理 【免费下载链接】picture-in-picture-chrome-extension 项目地址: https://gitcode.com/gh_mirrors/pi/picture-in-picture-chrome-extension 想要在浏览网页、处理文档的同时继续观看视频内容吗…...
从《吃豆人》到开放世界:聊聊Unity Navigation里Agent Radius和Cost的那些‘潜规则’
从《吃豆人》到开放世界:Unity Navigation中Agent Radius与Cost的隐藏逻辑1980年诞生的《吃豆人》用简单的迷宫路径定义了早期游戏AI的移动规则——幽灵们沿着固定路线巡逻,遇到转角时随机选择方向。这种设计在当时堪称革命性,但以今天的标准…...
Lovable内部工具开发方法论(从需求黑洞到用户自发推广的完整闭环)
更多请点击: https://kaifayun.com 第一章:Lovable内部工具开发方法论(从需求黑洞到用户自发推广的完整闭环) Lovable 方法论的核心不是交付功能,而是培育“工具依赖感”——当一线工程师在凌晨三点调试线上问题时&am…...
YOLOv8道路交通信号标志识别检测系统(项目源码+YOLO数据集+模型权重+UI界面+python+深度学习+环境配置)
摘要 道路交通信号标志的自动检测是智能驾驶与交通管理系统中的核心环节。本文基于YOLOv8目标检测算法,构建了一个涵盖21类常见交通信号标志的检测系统,包括禁令标志、指示标志、警告标志及信号灯等。模型在包含1376张训练图像、488张验证图像和229张测…...
终极Windows风扇控制指南:FanControl让你的电脑安静又高效
终极Windows风扇控制指南:FanControl让你的电脑安静又高效 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trendin…...
SpringBoot WebClient 介绍
目录一、什么是 WebClient?二、 WebClient 能解决什么问题?三、WebClient 和 RestTemplate 的区别四、WebClient 的核心优势1. 非阻塞(Non-Blocking)2. 支持异步3. 链式 API 更现代五、WebClient 的核心对象六、Mono 和 Flux 是什…...
