<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 | 云基础设施机制
探秘云基础设施机制:云计算的基石 一、云基础设施 —— 云计算的根基二、核心机制之网络:连接云的桥梁(一)虚拟网络边界ÿ…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
