0

0

c++的mutex和lock_guard如何使用 互斥锁保护共享资源【多线程】

尼克

尼克

发布时间:2026-01-01 18:59:41

|

668人浏览过

|

来源于php中文网

原创

std::mutex 和 std::lock_guard 是 C++ 多线程中安全同步共享资源的核心工具:前者提供手动加锁/解锁接口,后者通过 RAII 自动管理锁的生命周期,确保异常安全。

c++的mutex和lock_guard如何使用 互斥锁保护共享资源【多线程】

在多线程 C++ 程序中,std::mutexstd::lock_guard 是最常用、最安全的同步工具之一,用于保护共享资源不被多个线程同时修改,避免数据竞争(data race)和未定义行为。

mutex 用来上锁,lock_guard 自动管理锁的生命周期

std::mutex 是一个底层互斥量对象,提供 lock()unlock() 手动控制接口;但手动管理容易出错(比如忘记 unlock、异常提前退出导致死锁)。std::lock_guard 是 RAII 封装器:构造时自动加锁,析构时自动解锁(哪怕发生异常也会释放),非常可靠。

  • 必须用 std::mutex 对象的引用初始化 lock_guard,不能传值
  • lock_guard 是不可复制的(deleted copy constructor),只能移动或上构造

典型用法:保护共享变量或临界区

假设多个线程要累加同一个 int 变量:

std::mutex mtx;
int shared_counter = 0;

void increment() {
    std::lock_guard guard(mtx); // 构造即加锁
    ++shared_counter;                        // 访问共享资源
} // guard 离开作用域,自动调用 ~lock_guard() → 解锁
  • 所有访问 shared_counter 的地方都必须用同一把 mtx 加锁
  • 锁的作用域越小越好,只包裹真正需要保护的代码段
  • 不要跨函数持有锁(比如把 lock_guard 传给另一个函数),会延长临界区,降低并发性

常见错误和注意事项

容易忽略的细节会影响正确性和性能:

Kacha
Kacha

KaCha是一款革命性的AI写真工具,用AI技术将照片变成杰作!

下载
  • 全局或静态 mutex 要确保初始化顺序安全;推荐直接定义(C++11 起保证静态局部变量线程安全初始化)
  • 避免嵌套加锁同一 mutex(会导致死锁),如已持锁再调 lock() 是未定义行为;可用 std::recursive_mutex(但通常说明设计有问题)
  • 不要把 lock_guard 声明在 if 分支外却只在分支内使用——它必须在需要保护的代码前构造
  • 若需尝试加锁或带超时,用 std::unique_lock 替代,lock_guard 不支持这些操作

完整可运行示例

启动两个线程并发调用 increment() 10 万次,最终结果应为 200000:

#include 
#include 
#include 
#include 

std::mutex mtx;
int counter = 0;

void increment() {
    for (int i = 0; i < 100000; ++i) {
        std::lock_guard guard(mtx);
        ++counter;
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    t1.join(); t2.join();
    std::cout << "Final counter: " << counter << "\n"; // 输出 200000
}

去掉 lock_guardmtx,结果大概率小于 200000,甚至每次不同——这就是典型的竞态现象。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

989

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

50

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2025.12.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

371

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

563

2023.08.10

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

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

472

2023.08.10

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

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

108

2025.12.24

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

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

108

2025.12.24

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

65

2025.12.31

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.2万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3万人学习

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

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