C++ 线程互斥锁 lock_guard

std::lock_guard是 C++11 标准库提供的RAII 风格的互斥锁封装类,核心目的是自动管理互斥锁的加锁 / 解锁,从根本上避免 “忘记解锁导致死锁”“异常导致锁无法释放” 这类低级且致命的错误。

一、先理解核心:RAII 设计思想

lock_guard的底层是RAII(资源获取即初始化)机制 —— 简单说:

  • 构造时获取资源lock_guard对象创建时,自动调用互斥锁的lock()方法加锁;
  • 析构时释放资源lock_guard对象销毁时(比如出作用域),自动调用互斥锁的unlock()方法解锁。

这种 “自动性” 是解决多线程锁管理问题的关键,不用再手动记着unlock()

二、lock_guard的基本用法(对比手动加解锁)

先看错误的手动加解锁(容易出问题):

#include <mutex> std::mutex mtx; void wrong_func() { mtx.lock(); // 手动加锁 // 临界区操作:修改共享资源 int a = 10; // 忘记解锁 → 死锁! // 或如果临界区抛出异常,unlock()永远执行不到 → 死锁! // mtx.unlock(); }

再看正确的 lock_guard 用法(自动解锁):

#include <mutex> std::mutex mtx; void right_func() { // 创建lock_guard对象时,自动调用mtx.lock() std::lock_guard<std::mutex> lock(mtx); // 临界区:安全操作共享资源 int a = 10; } // lock_guard对象出作用域,析构时自动调用mtx.unlock() // 即使临界区抛出异常,析构函数也会执行 → 必解锁!

三、lock_guard的核心特性

1. 不可拷贝、不可移动

lock_guard被设计为 “只能在当前作用域使用”,禁止拷贝 / 移动,避免锁的管理权被非法转移:

std::lock_guard<std::mutex> lock1(mtx); // std::lock_guard<std::mutex> lock2 = lock1; // 编译错误:禁止拷贝 // std::lock_guard<std::mutex> lock3(std::move(lock1)); // 编译错误:禁止移动

2. 作用域决定解锁时机

lock_guard的解锁时机完全由作用域控制,你可以通过{}手动限定作用域,精准控制解锁时机:

void func() { { std::lock_guard<std::mutex> lock(mtx); // 短临界区:只保护必要的代码 shared_data = 100; } // 此处提前解锁,不影响后续非临界区代码 // 非临界区:无需持锁,提升并发效率 sleep(1); }

3. 轻量级、无额外开销

lock_guard是极简封装,没有额外的成员函数(比如unlock()/lock()),运行时几乎无性能损耗,适合简单的临界区保护。

4. 异常安全

这是lock_guard最核心的优势之一:即使临界区抛出异常,C++ 的异常机制会保证局部对象的析构函数执行,从而确保锁被释放:

void func_with_exception() { std::lock_guard<std::mutex> lock(mtx); // 临界区抛出异常 throw std::runtime_error("出错了"); // 无需手动unlock,析构函数会处理 } int main() { try { func_with_exception(); } catch (...) { // 捕获异常后,锁已经被释放,其他线程可正常获取 } return 0; }

四、lock_guardvsunique_lock(选型参考)

lock_guard是 “轻量版” 锁管理,std::unique_lock是 “功能版”,两者的核心区别如下:

特性std::lock_guardstd::unique_lock
自动加解锁✅ 支持✅ 支持
手动解锁(unlock()❌ 不支持✅ 支持
配合条件变量(cv.wait()❌ 不支持✅ 支持
性能极致轻量略重(有额外状态)
适用场景简单临界区保护复杂同步(如条件变量、手动控制解锁)

简单说:

  • 只要是 “加锁后,作用域结束解锁” 的简单场景,优先用lock_guard(轻量、高效);
  • 如果需要手动解锁、配合条件变量(比如cv.wait()需要解锁后阻塞),用unique_lock

五、完整示例:lock_guard 保护共享资源

#include <iostream> #include <thread> #include <mutex> #include <vector> std::mutex mtx; int shared_count = 0; // 共享资源 // 线程函数:累加共享变量 void increment(int n) { for (int i = 0; i < n; ++i) { // lock_guard自动加锁/解锁 std::lock_guard<std::mutex> lock(mtx); shared_count++; // 出循环迭代的作用域,自动解锁 } } int main() { std::vector<std::thread> threads; // 创建10个线程,每个线程累加1000次 for (int i = 0; i < 10; ++i) { threads.emplace_back(increment, 1000); } // 等待所有线程结束 for (auto& t : threads) { t.join(); } // 正确输出10000,无数据错乱 std::cout << "最终count值:" << shared_count << std::endl; return 0; }

总结

  1. std::lock_guard是 C++11 的 RAII 锁封装,构造加锁、析构解锁,核心解决 “忘记解锁 / 异常导致锁泄漏” 的问题;
  2. 轻量级、异常安全、不可拷贝,适合简单临界区的线程安全保护;
  3. 解锁时机由作用域决定,可通过{}手动缩小作用域,提升并发效率;
  4. 复杂同步场景(如条件变量)用unique_lock,简单场景优先用lock_guard

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1190848.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型应用工程师崛起之路:从入门到年薪60万+的完整指南

本文全面解析大模型应用工程师职业&#xff0c;介绍其定义、职责及广阔就业前景。数据显示该岗位70.8%月薪达20K-50K&#xff0c;年薪24-60万。文章提供系统学习路径&#xff0c;包括Python入门、大模型核心原理、Transformer架构、微调技术及企业级实战项目。职业发展可走技术…

人工智能应用-机器视觉:绘画大师 04.​​​​​​​​​​​​​​基于风格迁移的绘画大师

利用深度神经网络的这种内容&#xff0d;风格分离能力可以实现图片的风格迁移&#xff0c;即将一张图片 B 的风格迁移到另一张图片 A 上。换句话说&#xff0c;就是希望得到一张图片&#xff0c;该图片在内容上与 A 一致&#xff0c;但在风格上与 B 一致。实现这一目标的方法如…

计算机大数据毕设实战-基于django的蔬菜销售分析与预测可视化系统蔬菜产品销售预测可视化系统设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】

java毕业设计-基于springboot的(源码LW部署文档全bao远程调试代码讲解等) 博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、…

C++ 实现【精准可控】内存占用测试工具(指定内存大小,实打实占用物理内存,亲测可用)

前言在做程序性能验证、硬件资源测试、帧率影响实验&#xff08;比如验证内存占用量对摄像头 / 图像处理 / 算法推理帧率的影响&#xff09;时&#xff0c;我们经常需要人为、精准的占用指定大小的内存空间&#xff0c;以此模拟不同的内存负载环境。Windows 自带的内存查看工具…

typescript-类的静态属性和静态方法

我们上一节看到了类&#xff0c;里面都是类的实例属性和实例方法&#xff0c;即需要实例化后才可以进行访问的。什么是静态属性和静态方法&#xff1f;静态属性和静态方法是不需要实例化就可以访问的属性和方法(不需要实例化是指不需要new来生成对象)。还是以上一节的Person类举…

解锁AI记忆新范式:人类情景记忆如何提升大模型性能

本文探讨了如何借鉴人类情景记忆机制改进记忆增强型大语言模型。当前AI记忆系统在数据使用上低效且不符合人类认知直觉。文章对比了LLM与人脑记忆系统的五大关键差异&#xff1a;动态更新、事件分割、选择性、时间连续性和检索竞争。通过引入类人记忆机制&#xff0c;不仅能让A…

人工智能应用-机器视觉:绘画大师 05.还原毕加索的隐藏画

在艺术史上&#xff0c;一些大画家也曾经历过艰难时刻。例如&#xff0c;毕加索在 1901—1904 年间经历了极度的经济困境。 为了节省开支&#xff0c;他不得不在已经使用过的画布上创作新作品。如图 26.7所示&#xff0c;通过 X 射线扫描&#xff0c;人们发现毕加索在这一时期…

揭秘!提示工程架构师优化提示系统用户参与策略的关键技巧

揭秘&#xff01;提示工程架构师优化提示系统用户参与策略的关键技巧 一、引言&#xff1a;为什么你精心设计的AI系统&#xff0c;用户只用了一次&#xff1f; 上周&#xff0c;我朋友小A的吐槽让我印象深刻——他花了一个月搭建的AI旅游助手&#xff0c;上线3天用户留存率只…

【教程4>第10章>第25节】基于FPGA的图像Robert变换开发——理论分析与matlab仿真

目录 1.软件版本 2.图像Robert变换理论概述 3.图像Robert变换提取的matlab仿真测试 欢迎订阅FPGA/MATLAB/Simulink系列教程 《★教程1:matlab入门100例》 《★教程2:fpga入门100例》 《★教程3:simulink入门60例》 《★教程4:FPGA/MATLAB/Simulink联合开发入门与进阶X例》

学霸同款2026继续教育AI论文平台TOP10:毕业论文写作全测评

学霸同款2026继续教育AI论文平台TOP10&#xff1a;毕业论文写作全测评 2026继续教育AI论文平台测评&#xff1a;选对工具&#xff0c;提升写作效率 在当前学术环境日益严格的背景下&#xff0c;继续教育群体在撰写毕业论文时面临诸多挑战&#xff0c;如选题困难、文献检索繁琐、…

AAAI 2025论文分享|Agent4Edu:基于大语言模型生成式智能体的个性化学习模拟器

本推文介绍了AAAI 2025收录的一篇论文《Agent4Edu: Generating Learner Response Data by Generative Agents for Intelligent Education Systems》。Agent4Edu是一种基于大语言模型的个性化学习模拟器&#xff0c;旨在解决智能教育系统中高质量学习者响应数据稀缺、传统模拟方…

空气能十大领军品牌盘点:绿色能源时代的创新力量 - 资讯焦点

在“双碳”目标全面推进和清洁能源转型的浪潮中,空气能行业正迎来前所未有的发展机遇。作为高效、环保、可再生的能源利用方式,空气能技术已在采暖、制冷、热水等多个领域展现出强大的竞争力和市场潜力。本文盘点当前…

2025 AI大模型薪资狂欢:小白程序员入行最后黄金时机,年薪百万不是梦!非常详细建议收藏

文章分析了2025年AI大模型领域高薪就业趋势&#xff0c;指出供需失衡和政策支持导致AI岗位薪资暴涨&#xff0c;大模型算法工程师平均月薪7万。文章介绍五大高薪岗位及所需技能&#xff0c;提供提升竞争力的方法&#xff0c;并强调技术红利窗口期正在关闭&#xff0c;现在是入行…

Node.js代码统计神器

统计代码行数使用Node.js编写一个脚本&#xff0c;统计指定目录下所有文件的代码行数。const fs require(fs); const path require(path);function countLinesInFile(filePath) {const content fs.readFileSync(filePath, utf-8);return content.split(\n).length; }functio…

大数据毕设选题推荐:基于django的菜价可视化系统蔬菜销售分析与预测可视化系统【附源码、mysql、文档、调试+代码讲解+全bao等】

java毕业设计-基于springboot的(源码LW部署文档全bao远程调试代码讲解等) 博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、…

存储技术全解:从基础到前沿

系统存储机制深度剖析技术文章大纲存储基础概念存储介质的分类&#xff08;HDD、SSD、NVMe、NVM&#xff09;存储层次结构&#xff08;寄存器、缓存、主存、外存&#xff09;数据存取的基本原理&#xff08;寻址、读写、延迟&#xff09;文件系统与存储管理文件系统的核心组件&…

基于广义Benders分解法的综合能源系统优化规划Matlab代码

✅作者简介&#xff1a;热爱数据处理、建模、算法设计的Matlab仿真开发者。&#x1f34e;更多Matlab代码及仿真咨询内容点击 &#x1f517;&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码获取及仿真咨询内容私信。&#x1f447; 关注我…

基于多目标粒子群算法冷热电联供综合能源系统运行优化Matlab实现

✅作者简介&#xff1a;热爱数据处理、建模、算法设计的Matlab仿真开发者。&#x1f34e;更多Matlab代码及仿真咨询内容点击 &#x1f517;&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码获取及仿真咨询内容私信。&#x1f447; 关注我…

洛谷 P10962:Computer ← 换根DP

​【题目来源】https://www.luogu.com.cn/problem/P10962http://acm.hdu.edu.cn/showproblem.php?pid=2196【题目描述】某学校在一段时间前购买了第一台计算机(因此这台计算机的编号是 1)。在最近几年中,学校又购买…

activiti7的强制绑定角色问题

角色强绑定问题及解决方案 在使用若依的基础上,本打算将activiti7集成进去,结果在测试调用activiti的api时返回前端"没有权限,请联系管理员授权" 本来还以为是若依的权限校验,结果通过debug发现日志中报…