<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 | 云基础设施机制
探秘云基础设施机制:云计算的基石 一、云基础设施 —— 云计算的根基二、核心机制之网络:连接云的桥梁(一)虚拟网络边界ÿ…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
