0

0

c++如何互斥访问资源_c++中mutex锁用法【核心】

穿越時空

穿越時空

发布时间:2026-03-16 17:51:19

|

560人浏览过

|

来源于php中文网

原创

std::mutex必须配合RAII锁管理器使用,推荐std::lock_guard(轻量、自动析构)或std::unique_lock(支持try/timeout/手动unlock);多锁需固定顺序防死锁,优先用C++17的std::scoped_lock;禁止裸调lock/unlock、重复加锁、拷贝赋值,注意mutable修饰及静态初始化线程安全。

c++如何互斥访问资源_c++中mutex锁用法【核心】

std::mutex 必须配合 std::lock_guard 或 std::unique_lock 使用

直接调用 mutex.lock()mutex.unlock() 极易出错——忘记 unlock、异常中途跳出、提前 return,都会导致死锁。C++ 标准库不鼓励裸调用,而是靠 RAII 自动管理生命周期。

正确做法是把锁包装进作用域:只要 std::lock_guard 对象存在,互斥就生效;离开作用域自动释放。它轻量、无延迟、不可手动释放,适合绝大多数临界区。

  • std::lock_guard<:mutex></:mutex> 是最简选择,构造即加锁,析构即解锁,不支持转移、不支持尝试加锁、不支持超时
  • 需要 try_lock 或超时?改用 std::unique_lock<:mutex></:mutex>,但它稍重,且必须显式 unlock() 才能提前释放(否则仍靠析构)
  • 永远不要在同一个线程里对同一个 std::mutex 重复调用 lock() —— 这不是可重入锁,会死锁

多个 mutex 加锁顺序不一致 → 死锁高发区

当一段逻辑要同时操作两个共享对象(比如转账:从 A 扣款 + 给 B 加款),就得锁两个 std::mutex。如果线程 1 先锁 A 再锁 B,线程 2 偏偏先锁 B 再锁 A,就卡住了。

标准解法是固定全局加锁顺序,例如按对象地址排序:

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

阿里妈妈·创意中心
阿里妈妈·创意中心

阿里妈妈营销创意中心

下载
if (&mutex_a < &mutex_b) {
    std::lock_guard<std::mutex> lock1(mutex_a);
    std::lock_guard<std::mutex> lock2(mutex_b);
} else {
    std::lock_guard<std::mutex> lock1(mutex_b);
    std::lock_guard<std::mutex> lock2(mutex_a);
}
  • 更简洁的方式是用 std::scoped_lock(C++17 起),它自动按地址顺序加多个锁,且异常安全:std::scoped_lock lock(mutex_a, mutex_b);
  • 避免跨函数传 std::mutex* 并在不同地方随意加锁——逻辑分散后顺序极易失控
  • 调试时若程序卡住不动,优先检查是否有多 mutex 场景且没统一顺序

std::mutex 不可拷贝、不可移动,别存 vector 或作为类成员乱初始化

std::mutex 禁止拷贝和赋值,编译器会直接报错。常见误用是想动态创建一堆带锁的对象,写成 std::vector<std::mutex> 或在类里写 std::mutex mtx = std::mutex(); —— 后者调用默认构造没问题,但赋值那行非法。

  • 要管理多个 mutex?用 std::vector<std::unique_ptr<std::mutex>> 或直接 std::vector<std::mutex>(C++11 起允许默认构造的容器,但不能 push_back 未构造的 mutex)
  • 类中声明 mutable std::mutex mtx; 是常见模式(尤其用于缓存等只读接口里的写操作),注意加 mutable 否则 const 成员函数里无法调用 mtx.lock()
  • 全局或静态 std::mutex 安全,但局部静态 mutex(如函数内 static std::mutex m;)在首次调用时才构造,线程安全由编译器保证(C++11 起)

std::mutex 阻塞式、无超时、不响应中断,替代方案要看场景

std::mutexlock() 会一直等下去,没有“等 10ms 失败就走”的能力。如果你需要非阻塞或带超时的同步,它就不合适。

  • 想试试看能不能抢到锁?用 std::unique_lock::try_lock(),返回 bool
  • 要等一段时间?用 std::unique_lock::try_lock_for()try_lock_until()
  • 真正需要异步取消或中断等待?std::mutex 做不到,得换 std::condition_variable 配合,或上平台级原语(如 pthread_mutex_timedlock)
  • 性能敏感且临界区极短?考虑 std::atomic_flag 手写自旋锁,但注意别空转太久耗 CPU

mutex 的设计目标就是简单可靠,不是灵活多变。用错场景时,问题往往不出在“怎么写”,而出在“该不该用它”。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

565

2023.09.20

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

565

2023.09.20

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

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

2005

2023.10.19

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

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

681

2025.10.17

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

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

2440

2025.12.29

java接口相关教程
java接口相关教程

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

49

2026.01.19

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

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

448

2023.07.18

堆和栈区别
堆和栈区别

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

606

2023.08.10

chatgpt使用指南
chatgpt使用指南

本专题整合了chatgpt使用教程、新手使用说明等等相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

热门下载

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

精品课程

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

共94课时 | 11.5万人学习

C 教程
C 教程

共75课时 | 5.5万人学习

C++教程
C++教程

共115课时 | 22.2万人学习

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

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