0

0

C++ 线程安全怎么保证 C++ lock_guard与mutex使用指南【并发】

冰火之心

冰火之心

发布时间:2026-01-25 11:44:55

|

405人浏览过

|

来源于php中文网

原创

直接调用 mutex::lock()/unlock() 危险,因异常、提前 return 或分支遗漏会导致死锁或资源永久占用;C++ 无 finally 机制,无法保证 unlock() 执行。

c++ 线程安全怎么保证 c++ lock_guard与mutex使用指南【并发】

为什么直接用 mutex::lock()unlock() 很危险

手动配对调用 lock()unlock() 看似简单,但只要中间抛异常、提前 return 或逻辑分支遗漏,就会导致死锁或资源永久占用。C++ 没有“finally”语义,无法保证 unlock() 一定执行。

常见错误现象:std::system_error: resource deadlock would have occurred、程序卡死在某次 lock()、多个线程反复争抢却无进展。

实操建议:

  • 永远避免裸写 mtx.lock() / mtx.unlock()
  • 哪怕只有一行临界操作,也必须用 RAII 封装
  • mutex 声明为类成员时,注意它不可拷贝——别试图传值或放入 std::vector(会编译失败)

lock_guard 的正确用法和常见误用

lock_guard 是最轻量的 RAII 封装,构造即加锁,析构即解锁,不支持转移、不支持延迟锁定,适合绝大多数简单场景。

立即学习C++免费学习笔记(深入)”;

示例:

std::mutex mtx;
int counter = 0;

void increment() {
    std::lock_guard lock(mtx); // 构造时自动 lock()
    ++counter; // 临界区
} // 出作用域自动 unlock() —— 即使这里 throw 异常也安全

容易踩的坑:

Picsart
Picsart

Picsart是全球最大的数字创作平台。

下载
  • lock_guard 声明成指针(new std::lock_guard<...>(mtx)):析构不会被自动触发
  • 作用域传递 lock_guard 对象:它不可移动也不可复制,编译报错 use of deleted function
  • 在 if 分支里声明,但临界区逻辑实际需要覆盖整个函数:作用域太小,锁过早释放

什么时候该换 unique_lock 而不是硬撑 lock_guard

lock_guard 够用就别换。只有当你需要以下能力时,才考虑 unique_lock

  • 延迟加锁(构造时不锁,后面调 lock()try_lock()
  • 手动控制解锁时机(比如临界区后半段不需要锁,提前 unlock() 提高并发度)
  • 配合条件变量 std::condition_variable::wait()(它要求传入 unique_lock
  • 需要把锁对象移出作用域(例如返回、存入容器、传参)

性能影响:两者底层都只是封装了 mutex 操作,unique_lock 多一个布尔标记位,开销几乎可忽略;但滥用会增加理解成本和出错概率。

全局 mutex 和静态局部 mutex 初始化陷阱

全局或静态 std::mutex 对象在 C++11 及以后是线程安全初始化的(即首次使用前完成构造),但前提是不能在动态初始化阶段(如其他全局对象的构造函数中)访问它——否则可能触发未定义行为。

更稳妥的做法是用静态局部变量延迟初始化:

std::mutex& get_counter_mutex() {
    static std::mutex mtx; // 首次调用时线程安全构造
    return mtx;
}

注意:static std::mutex 在函数内定义是安全的;但 static std::mutex* 并不解决初始化问题,反而引入指针生命周期管理负担。

真正容易被忽略的是:多个互不相关的全局 mutex 如果按不同顺序在多线程中首次访问,仍可能引发初始化竞态——所以尽量避免在全局对象构造器里触碰任何 mutex

相关专题

更多
resource是什么文件
resource是什么文件

Resource文件是一种特殊类型的文件,它通常用于存储应用程序或操作系统中的各种资源信息。它们在应用程序开发中起着关键作用,并在跨平台开发和国际化方面提供支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

152

2023.12.20

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

769

2023.08.22

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

482

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

143

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

5

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

11

2026.01.21

function是什么
function是什么

function是函数的意思,是一段具有特定功能的可重复使用的代码块,是程序的基本组成单元之一,可以接受输入参数,执行特定的操作,并返回结果。本专题为大家提供function是什么的相关的文章、下载、课程内容,供大家免费下载体验。

481

2023.08.04

js函数function用法
js函数function用法

js函数function用法有:1、声明函数;2、调用函数;3、函数参数;4、函数返回值;5、匿名函数;6、函数作为参数;7、函数作用域;8、递归函数。本专题提供js函数function用法的相关文章内容,大家可以免费阅读。

163

2023.10.07

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

41

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号