当前位置: 首页 > ops >正文

C++ 条件变量 通知 cv.notify_all() 先释放锁再通知

简短的回答是:先释放锁,再通知(notify_one 或 notify_all)通常是更优的选择。 虽然标准允许两种顺序,但“先解锁,后通知”的性能通常更好。

下面我们来详细解释原因和两种方式的区别。

  1. 先通知,后释放锁 (notify then unlock)
// 假设 mu 是一个 std::mutex, cv 是一个 std::condition_variable
{std::lock_guard<std::mutex> lk(mu); // 持有锁// ... 修改共享数据 ...ready = true;cv.notify_one(); // 1. 先通知(锁仍被持有)
} // 2. lock_guard 超出作用域,自动释放锁

可能发生的问题:性能损耗(“惊群”效应与立即阻塞)
当你在持有锁的情况下调用 notify_one():

  1. 系统会唤醒一个(或多个,如果是 notify_all)正在等待(waiting)的线程。
  2. 被唤醒的线程会立即尝试获取与条件变量关联的互斥锁(这是 std::condition_variable::wait 操作的固有步骤)。
  3. 但是,此时通知线程还持有这把锁!所以被唤醒的线程无法立即获取锁,它会被迫再次进入阻塞(blocking)状态,等待通知线程释放锁。
  4. 通知线程在 } 处释放锁。
  5. 被唤醒的线程终于可以再次尝试并成功获取锁。

这个过程导致了一次无谓的上下文切换:被唤醒的线程什么都没做就又被阻塞了。在高性能要求的场景下,这种额外的切换会带来不必要的开销。

  1. 先释放锁,后通知 (unlock then notify)
{std::unique_lock<std::mutex> lk(mu); // 持有锁// ... 修改共享数据 ...ready = true;lk.unlock(); // 1. 手动先释放锁cv.notify_one(); // 2. 再通知(锁已被释放)
}
// 或者使用一个额外的作用域让 lock_guard 提前释放
{{std::lock_guard<std::mutex> lk(mu);// ... 修改共享数据 ...ready = true;} // 锁在这里被释放cv.notify_one(); // 然后在没有锁的情况下通知
}

优点:性能更优
当你先释放锁再通知:

  1. 锁已经被释放。
  2. 调用 notify_one() 唤醒一个等待线程。
  3. 被唤醒的线程尝试获取互斥锁,此时锁是空闲的,所以它有很大概率能立即成功获取并继续执行,避免了不必要的二次阻塞和上下文切换。

这使得线程调度更加高效。

http://www.xdnf.cn/news/20210.html

相关文章:

  • [光学原理与应用-428]:非线性光学 - 为什么要改变光的波长/频率,获得特点波长/频率的光?
  • RocketMQ如何处理消息堆积
  • 云某惠旧案再审可能性与商业创新实践:积分运营的边界与实体商家机遇
  • 【设计模式】 工厂方法模式
  • 【YOLOv11】2.安装Anaconda3
  • 机器人控制器开发(定位算法——map、odom、baselink关联与差异)
  • JavaScript的库简介
  • 离散数学学习指导与习题解析
  • react生命周期,详细版本
  • 运筹学——求解线性规划的单纯形法
  • solidity的高阶语法2
  • AI工程师对于AI的突发奇想
  • Docker Desktop 安装 Linux(告别传统的虚拟机VMware)
  • Date、BigDecimal类型值转换
  • 残差去噪扩散模型
  • 字节跳动OmniHuman-1.5发布:单图+音频秒变超真实视频,AI数字人技术再升级
  • HOT100--Day13--104. 二叉树的最大深度,226. 翻转二叉树,101. 对称二叉树
  • Docker入门到精通:从零基础到生产部署
  • 如何在路由器上配置DHCP服务器?
  • 本体论中的公理与规则——从经典逻辑到神经符号融合的演进
  • Hive on Tez/Spark 执行引擎对比与优化
  • AI浪潮下,人类创造力的“危”与“机”
  • 2026届大数据毕业设计选题推荐-基于大数据旅游数据分析与推荐系统 爬虫数据可视化分析
  • JAVA基本文件操作
  • 【74页PPT】MES简介(附下载方式)
  • TensorFlow 面试题及详细答案 120道(101-110)-- 底层原理与扩展
  • C++笔记之软件设计原则总结
  • Lua > Mac Mini M4安装openresty
  • 基于Transformer 实现车辆检测与车牌识别(一)
  • disable CASCADE主键失败 ORA-2297 And ORA-2433