当前位置: 首页 > news >正文

第16天:C++多线程完全指南 - 从基础到现代并发编程

第16天:C++多线程完全指南 - 从基础到现代并发编程

一、多线程基础概念

1. 线程创建与管理(C++11)

#include <iostream>
#include <thread>void hello() {std::cout << "Hello from thread " << std::this_thread::get_id() << "\n";
}int main() {std::thread t1(hello);std::thread t2([](){std::cout << "Lambda thread running\n";});t1.join();  // 等待线程完成t2.join();// 输出可能交错:// Hello from thread 140245230233344// Lambda thread running
}

2. 并发与并行区别

  • 并发:交替处理多个任务(单核)
  • 并行:同时处理多个任务(多核)
// 查看硬件支持线程数
unsigned int n = std::thread::hardware_concurrency();
std::cout << n << " concurrent threads supported\n";

二、线程同步核心机制

1. 互斥锁(mutex)与RAII

#include <mutex>std::mutex mtx;
int shared_data = 0;void safe_increment() {std::lock_guard<std::mutex> lock(mtx); // 自动释放锁++shared_data;  // 临界区操作
}int main() {std::thread threads[10];for (auto& t : threads) {t = std::thread(safe_increment);}for (auto& t : threads) {t.join();}std::cout << "Final value: " << shared_data; // 正确输出10
}

2. 条件变量(生产者-消费者模式)

#include <queue>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
std::queue<int> data_queue;void producer() {for (int i=0; i<5; ++i) {{std::lock_guard<std::mutex> lock(mtx);data_queue.push(i);}cv.notify_one();  // 通知消费者std::this_thread::sleep_for(std::chrono::milliseconds(100));}
}void consumer() {while(true) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return !data_queue.empty(); });int data = data_queue.front();data_queue.pop();lock.unlock();std::cout << "Consumed: " << data << "\n";if(data == 4) break;}
}

三、现代C++并发特性

1. 异步任务(std::async)

#include <future>int compute(int x) {return x * x;
}int main() {auto future = std::async(std::launch::async, compute, 12);std::cout << "Result: " << future.get();  // 输出144
}

2. 原子操作(std::atomic)

#include <atomic>std::atomic<int> counter(0);  // 无需锁的线程安全计数器void increment() {for (int i=0; i<100000; ++i) {++counter;  // 原子操作}
}// 测试:两个线程同时递增
// 最终结果正确为200000

四、线程安全设计模式

1. 线程局部存储(thread_local)

thread_local int tls_var = 0;  // 每个线程独立副本void thread_func() {++tls_var;std::cout << "Thread " << std::this_thread::get_id() << ": " << tls_var << "\n";
}// 每个线程输出自己的递增结果

2. 线程池实现(C++17)

#include <vector>
#include <functional>
#include <queue>class ThreadPool {std::vector<std::thread> workers;std::queue<std::function<void()>> tasks;std::mutex queue_mutex;std::condition_variable condition;bool stop = false;public:ThreadPool(size_t threads) {for(size_t i=0; i<threads; ++i) {workers.emplace_back([this]{while(true) {std::function<void()> task;{std::unique_lock<std::mutex> lock(queue_mutex);condition.wait(lock, [this]{ return stop || !tasks.empty(); });if(stop && tasks.empty()) return;task = std::move(tasks.front());tasks.pop();}task();}});}}template<class F>void enqueue(F&& f) {{std::lock_guard<std::mutex> lock(queue_mutex);tasks.emplace(std::forward<F>(f));}condition.notify_one();}~ThreadPool() {{std::lock_guard<std::mutex> lock(queue_mutex);stop = true;}condition.notify_all();for(auto& worker : workers)worker.join();}
};

五、并发编程陷阱与调试

1. 死锁检测示例

std::mutex m1, m2;void thread_A() {std::lock_guard<std::mutex> lock1(m1);std::this_thread::sleep_for(std::chrono::milliseconds(100));std::lock_guard<std::mutex> lock2(m2); // 可能死锁点
}void thread_B() {std::lock_guard<std::mutex> lock2(m2);std::this_thread::sleep_for(std::chrono::milliseconds(100));std::lock_guard<std::mutex> lock1(m1); // 可能死锁点
}// 解决方案:使用std::lock同时锁定多个互斥量
void safe_lock() {std::lock(m1, m2);std::lock_guard<std::mutex> lock1(m1, std::adopt_lock);std::lock_guard<std::mutex> lock2(m2, std::adopt_lock);
}

六、现代C++并发增强

1. C++20信号量(semaphore)

#include <semaphore>std::counting_semaphore<5> sem(3);  // 允许3个同时访问void limited_thread() {sem.acquire();// 访问受限资源sem.release();
}

2. 屏障(C++20 barrier)

std::barrier sync_point(3);  // 等待3个线程到达void worker() {// Phase 1sync_point.arrive_and_wait();// Phase 2(所有线程完成Phase1后继续)
}

七、常见问题解答

Q:如何检测数据竞争?

  • 使用ThreadSanitizer编译:
g++ -fsanitize=thread -g -O1 program.cpp
  • 示例输出:
WARNING: ThreadSanitizer: data race

Q:std::mutex和std::shared_mutex区别?

  • std::mutex:独占锁
  • std::shared_mutex:读写锁(C++17)
std::shared_mutex smtx;// 写操作使用独占锁
{std::unique_lock lock(smtx);data = new_value;
}// 读操作使用共享锁
{std::shared_lock lock(smtx);read_data = data;
}

八、今日总结

✅ 核心掌握:

  • 🧵 线程生命周期管理(创建、等待、分离)
  • 🔒 同步原语使用场景(mutex/atomic/condition_variable)
  • 🚧 典型并发问题检测与预防(死锁、数据竞争)

相关文章:

第16天:C++多线程完全指南 - 从基础到现代并发编程

第16天&#xff1a;C多线程完全指南 - 从基础到现代并发编程 一、多线程基础概念 1. 线程创建与管理&#xff08;C11&#xff09; #include <iostream> #include <thread>void hello() {std::cout << "Hello from thread " << std::this_…...

中科大计算机网络原理 1.5 Internt结构和ISP

一、互联网的层次化架构 ‌覆盖范围分层‌ ‌主干网&#xff08;Tier-1级&#xff09;‌ 国家级或行业级核心网络&#xff0c;承担跨区域数据传输和全球互联功能。例如中国的四大主干网&#xff08;ChinaNET、CERNET等&#xff09;以及跨国运营商&#xff08;如AT&T、Deuts…...

Windows安装sql server2017

看了下官网的文档&#xff0c;似乎只有ubuntu18.04可以安装&#xff0c;其他debian系的都不行&#xff0c;还有通过docker的方式安装的。 双击进入下载的ISO&#xff0c;点击执行可执行文件&#xff0c;并选择“是” 不要勾选 警告而已&#xff0c;不必理会 至少勾选这两…...

计算机网络之传输层(tcp协议)

一、TCP协议的特点 面向连接&#xff1a;TCP使用面向连接的通信模式&#xff0c;通信双方需要先建立连接&#xff0c;然后才能进行数据的传输。连接建立过程采用三次握手的方式。 可靠性&#xff1a;TCP提供可靠的数据传输服务&#xff0c;确保数据的完整性、有序性和正确性。…...

从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)?

本文首发&#xff1a;从零到一&#xff1a;如何用阿里云百炼和火山引擎搭建专属 AI 助手&#xff08;DeepSeek&#xff09;&#xff1f; 阿里云百炼和火山引擎都推出了免费的 DeepSeek 模型体验额度&#xff0c;今天我和大家一起搭建一个本地的专属 AI 助手。  阿里云百炼为 …...

Open3D解决SceneWidget加入布局中消失的问题

Open3D解决SceneWidget加入布局中消失的问题 Open3D解决SceneWidget加入布局中消失的问题1. 问题2. 问题代码3. 解决 Open3D解决SceneWidget加入布局中消失的问题 1. 问题 把SceneWidget加到布局管理其中图形可以展示出来&#xff0c;但是鼠标点击就消失了。 stackoverflow上已…...

计算机毕业设计Python+DeepSeek-R1大模型游戏推荐系统 Steam游戏推荐系统 游戏可视化 游戏数据分析(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

Linux笔记---缓冲区

1. 什么是缓冲区 在计算机系统中&#xff0c;缓冲区&#xff08;Buffer&#xff09; 是一种临时存储数据的区域&#xff0c;主要用于协调不同速度或不同时序的组件之间的数据传输&#xff0c;以提高效率并减少资源冲突。它是系统设计中的重要概念&#xff0c;尤其在I/O操作、网…...

如何流畅访问github

1.传输数据原理 本地计算机通过本地网接入运营骨干网&#xff0c;经过DNS域名解析&#xff0c;将输入的字符解析为要连接的真实IP地址&#xff0c;服务器返还一个数据包(github)给计算机 2.原因 DNS域名污染-DNS解析出现问题&#xff0c;导致访问一个不存在的服务器 3.解决…...

java基础+面向对象

Java基础语法 CMD命令 cls 清屏 cd 目录进入文件 cd… 退回 dir 查看当前目录所有文件 E&#xff1a;进入E盘 exit 退出 环境变量就是不用去专门的盘符去找&#xff0c;直接去环境变量里找到文件 语言优势 编译型语言c&#xff1a; 整体翻译 解释型语言python&#x…...

Linux 检测内存泄漏方法总结

文章目录 strace检测asan内存检测linux下gperf工具&#xff08;tcmalloc&#xff09;检查C/C代码内存泄露问题参考 strace检测 &#xff08;1&#xff09;启动程序 &#xff08;2&#xff09; strace -f -p <PID> -tt -e brk,mmap,mmap2,munmapbrk 变大 → 说明堆增长…...

本地部署deepseek大模型后使用c# winform调用(可离线)

介于最近deepseek的大火&#xff0c;我就在想能不能用winform也玩一玩本地部署&#xff0c;于是经过查阅资料&#xff0c;然后了解到ollama部署deepseek,最后用ollama sharp NUGet包来实现winform调用ollama 部署的deepseek。 本项目使用Vs2022和.net 8.0开发&#xff0c;ollam…...

Python----数据分析(Numpy:安装,数组创建,切片和索引,数组的属性,数据类型,数组形状,数组的运算,基本函数)

一、 Numpy库简介 1.1、概念 NumPy(Numerical Python)是一个开源的Python科学计算库&#xff0c;旨在为Python提供 高性能的多维数组对象和一系列工具。NumPy数组是Python数据分析的基础&#xff0c;许多 其他的数据处理库&#xff08;如Pandas、SciPy&#xff09;都依赖于Num…...

Leetcode-最大矩形(单调栈)

一、题目描述 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵&#xff0c;找出只包含 1 的最大矩形&#xff0c;并返回其面积。 输入&#xff1a;matrix [["1","0","1","0","0"],["1","0&…...

域内委派维权

为某个服务账户配置 krbtgt 用户的非约束性委派或基于资源的约束性委派。这里我的 krbtgt 的基于资源约束性委派我利用不了&#xff0c;所以使用的是域控的机器账户 dc01$ 进行维权。 抓取所有 hash。 mimikatz.exe "privilege::debug" "lsadump::dcsync /doma…...

leetcode---LCR 140.训练计划

给定一个头节点为 head 的链表用于记录一系列核心肌群训练项目编号&#xff0c;请查找并返回倒数第 cnt 个训练项目编号。 示例 1&#xff1a; 输入&#xff1a;head [2,4,7,8], cnt 1 输出&#xff1a;8 提示&#xff1a; 1 < head.length < 1000 < head[i] <…...

Linux基础 -- ARM 32位常用机器码(指令)整理

ARM 32位常用机器码&#xff08;指令&#xff09;整理 1. 数据处理指令&#xff08;运算、逻辑、比较&#xff09; 指令含义示例备注MOV赋值&#xff08;寄存器传输&#xff09;MOV R0, R1直接将 R1 复制到 R0MVN取反MVN R0, R1R0 ~R1ADD加法ADD R0, R1, R2R0 R1 R2ADC带进…...

内存中的缓存区

在 Java 的 I/O 流设计中&#xff0c;BufferedInputStream 和 BufferedOutputStream 的“缓冲区”是 内存中的缓存区&#xff08;具体是 JVM 堆内存的一部分&#xff09;&#xff0c;但它们的作用是优化数据的传输效率&#xff0c;并不是直接操作硬盘和内存之间的缓存。以下是详…...

基于 Spring Boot 的 +Vue“宠物咖啡馆平台” 系统的设计与实现

大家好&#xff0c;今天要和大家聊的是一款基于 Spring Boot 的 “宠物咖啡馆平台” 系统的设计与实现。项目源码以及部署相关事宜请联系我&#xff0c;文末附上联系方式。 项目简介 基于 Spring Boot 的 “宠物咖啡馆平台” 系统设计与实现的主要使用者分为 管理员、用户 和…...

LeetCode 解题思路 7(Hot 100)

解题思路&#xff1a; 初始化窗口元素&#xff1a; 遍历前 k 个元素&#xff0c;构建初始单调队列。若当前索引对应值大于等于队尾索引对应值&#xff0c;移除队尾索引&#xff0c;将当前索引加入队尾。遍历结束时当前队头索引即为当前窗口最大值&#xff0c;将其存入结果数组…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...