新闻中心

C++中的std::mutex和std::recursive_mutex有什么区别?C++互斥锁选择【多线程】

2025-12-12
浏览次数:
返回列表
std::mutex不支持同线程重复加锁,否则导致未定义行为;std::recursive_mutex允许同线程多次加锁并计数管理,仅在明确需要重入时选用,优先使用更轻量安全的std::mutex。

c++中的std::mutex和std::recursive_mutex有什么区别?c++互斥锁选择【多线程】

std::mutex 是普通互斥锁,不支持同一线程重复加锁

它是最基础的互斥机制,一旦线程成功调用 lock(),再次调用就会导致**未定义行为**(通常是死锁或程序崩溃)。这符合“一个锁、一次持有”的设计原则,适合保护临界资源且逻辑清晰的场景。

例如:一个函数内部加锁后调用另一个也试图加同一把锁的函数,用 std::mutex 就会出问题:

  • funcA() → lock(mtx) → funcB() → lock(mtx) ❌ 崩溃或死锁

std::recursive_mutex 允许同一线程多次加锁,但需对应次数解锁

它内部维护一个**持有计数器**和**持有线程ID**。同一线程反复调用 lock() 会递增计数;每次 unlock() 减一;只有计数归零时才真正释放锁。适合递归调用、重入式设计或封装层次较深的代码。

注意:跨线程仍互斥,只是放宽了同一线程的限制。使用不当容易掩盖设计缺陷,比如隐藏了本该用不同锁或重构逻辑的问题。

Procys Procys

AI驱动的发票数据处理

Procys 102 查看详情 Procys

选择建议:优先用 std::mutex,仅在明确需要重入时选 recursive_mutex

多数情况下,std::mutex 更轻量、更安全、更易排查问题。C++ 标准库中绝大多数容器和工具都基于非递归锁设计。

  • 如果你能通过调整函数职责、拆分临界区、或用 RAII(如 std::lock_guard)避免重复加锁 → 用 std::mutex
  • 如果确实存在合法递归调用(如解析嵌套表达式、事件回调再触发自身),且难以重构 → 可考虑 std::recursive_mutex
  • 性能上,recursive_mutex 有额外计数和判断开销,虽然微小,但非必要不引入

别忽略替代方案:可重入 ≠ 必须用 recursive_mutex

有时你以为需要重入,其实只是锁粒度或设计不合理。可以尝试:

  • 把大锁拆成多个细粒度锁,降低冲突和嵌套需求
  • 用 std::shared_mutex(C++17)区分读写,提升并发性
  • 用 std::scoped_lock 或 std::unique_lock 配合 try_lock 等灵活控制
  • 用无锁结构(如原子变量、lock-free queue)替代部分锁场景

基本上就这些。选对锁不是炫技,而是让多线程逻辑更清晰、更可靠、更容易维护。

以上就是C++中的std::mutex和std::recursive_mutex有什么区别?C++互斥锁选择【多线程】的详细内容,更多请关注其它相关文章!


# ai  # seo现在能做的产品吗  # 乌海市包头网站建设  # seo1动漫图片  # 胶州网站建设商家  # 温州网站建设新感觉建站  # 网站建设广告图片模板  # 有什么区别  # 不支持  # 就会  # 重构  # 如何使用  # 互斥  # 死锁  # 加锁  # 多线程  # 递归  # red  # 标准库  # 无锁  # 区别  # c++  # 工具  # 西安网站优化建设团队  # 横岗全国网站推广  # 赤峰网站建设招商推荐会  # 丰都做网站建设 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: sublime怎么覆盖插件的默认快捷键_sublime快捷键优先级与设置  怎样更改Windows系统的默认安装路径_避免C盘爆满的终极设置【技巧】  中兴BladeV30怎样用测距估书架层高_iPhone中兴BladeV30测距估书架层高【家装参考】  夸克浏览器桌面版同步不了书签怎么处理 夸克浏览器跨设备同步异常解决方案  J*aScript 字符串标签转换:使用正则表达式高效替换  必由学官网入口 必由学教师登录入口  NRF24L01数据传输深度解析:解决大载荷接收异常与分包策略  Win11蓝牙耳机断连怎么解决 Win11蓝牙设置重新配对与驱动更新【技巧】  Win11怎么开启高性能模式_Windows 11电源计划优化设置  如何提高微信支付的安全性_微信支付安全防护与设置建议  Lar*el Form Request中唯一性验证在更新操作中的正确实现  Golang如何使用new_Go new分配内存机制讲解  Win10快速启动功能利弊分析 Win10开启或关闭快速启动教程【技巧】  邮政编码查询不到怎么办_邮政编码查询不到的常见原因与对策  如何使用CaptainHook和Composer管理Git钩子_在提交前自动运行代码检查的Composer配置  黑鲨3Pro怎样在相册开漫画风滤镜_iPhone黑鲨3Pro相册开漫画风滤镜【趣味滤镜】  海棠电脑版入口_通过电脑访问海棠官网阅读  使用Python高效删除Word宏并转换DOCM为DOCX格式  TikTok搜索结果不显示如何解决 TikTok搜索刷新优化方法  《刺客信条4:黑旗》重制版新细节曝光:无缝加载 地图更细致!  荣耀Play7TPro怎样在信息App置顶客服对话_iPhone荣耀Play7TPro信息App置顶客服对话【优先查看】  sublime怎么格式化代码_sublime代码美化与一键排版插件配置  电脑屏幕颜色不舒服怎么办_Windows夜间模式与色彩校准教程【护眼技巧】  Bing引擎入口最新2025 Bing搜索免费官方登录  Composer的 archive 命令怎么用_快速打包你的PHP项目及其Composer依赖  Angular Material 垂直步进器:实现底部到顶部排序的教程  一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法  韩小圈电脑版在线入口_网页版免费登录地址  如何使用Rector自动化升级旧代码_通过Composer安装和配置Rector进行代码重构  PPT平滑切换怎么做 PPT炫酷“平滑”切换动画制作教程【必学】  steam官方网页快速访问 steam账号注册全流程  《噬血代码2》新预告片发布 展示游戏剧情  php源码怎么在电脑上测试_电脑测试php源码方法步骤【教程】  Django AJAX 文件上传教程:解决图片无法保存到模型的常见问题  Golang如何实现Web文件静态资源服务器_Golang静态资源服务器开发与实践  word中如何让数字纵向排列_Word数字纵向排列方法  哔哩哔哩忘记密码了怎么找回_哔哩哔哩密码找回方法  如何在低配置电脑上搭建轻量级J*a环境_占用更小的环境选择技巧  AO3官方镜像站点汇总 AO3同人作品网页版直达链接  J*aScript生成器_j*ascript异步迭代  微信聊天记录怎么加密_微信聊天记录加密方法  Golang如何优化CPU绑定任务分配策略_Golang CPU任务分配优化实践  2025俄罗斯Yandex最新入口 官方网站地址及浏览器下载指南  如何将HTML表格多行数据保存到Google Sheet  蛙漫2日版入口 WAMAN2(日版)无删减漫画官网链接  mysql如何设置表访问权限_mysql表访问权限配置  为什么我的微信朋友圈看不到别人的更新_微信朋友圈更新显示异常解决方法  J*aScript中在Map循环中检测并处理空数组元素  抖音网页版平台入口 抖音网页版官网在线访问教程  c++中的const_cast和reinterpret_cast怎么用_c++四种类型转换 

搜索