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

thread 的mutex优化

std::mutex mtx;
int shared_data = 0;void increment() {std::lock_guard<std::mutex> lock(mtx);  // 自动加锁shared_data++;  // 临界区
}  // 离开作用域时自动解锁

std::lock_guard 在离开作用域时自动解锁的行为是基于 C++ 的 RAII (Resource Acquisition Is Initialization) 设计模式实现的。这种模式将资源的生命周期与对象的生命周期绑定,确保资源在对象析构时自动释放。

RAII 机制解析

当你创建一个 std::lock_guard 对象时:

  1. 构造函数:在对象创建时立即获取锁(调用 mutex::lock()
  2. 析构函数:在对象生命周期结束时自动释放锁(调用 mutex::unlock()
template <typename Mutex>
class lock_guard {
public:explicit lock_guard(Mutex& m) : mtx(m) {mtx.lock();  // 构造时加锁}~lock_guard() {mtx.unlock();  // 析构时解锁}private:Mutex& mtx;  // 引用底层互斥锁
};

作用域规则与对象生命周期

C++ 规定,局部对象在离开其定义的作用域时会自动析构。例如:

void func() {// 进入作用域{  // 子作用域开始std::lock_guard<std::mutex> lock(mtx);  // 构造 + 加锁// 临界区}  // 子作用域结束 → lock 对象析构 → 自动解锁// lock 对象在此处已不存在
}  // 函数结束 → 所有局部对象析构

为什么这种设计更安全?

对比手动管理锁的方式:

// 手动管理锁(不推荐)
void increment() {mtx.lock();  // 手动加锁try {shared_data++;  // 临界区// 如果此处抛出异常,锁将不会被释放} catch (...) {mtx.unlock();  // 需要在每个异常处理路径中解锁throw;}mtx.unlock();  // 手动解锁(必须确保执行)
}

手动管理锁的问题:

  1. 容易遗漏解锁:如果临界区中有多个 return 语句或异常抛出
  2. 代码冗余:每个锁都需要配套的解锁操作
  3. 难以维护:修改临界区逻辑时可能忘记调整解锁位置

RAII 的优势

使用 std::lock_guard 的好处:

  1. 自动解锁:无论临界区如何退出(正常返回或异常),锁都会被释放
  2. 代码简洁:无需显式编写 unlock 语句
  3. 异常安全:即使发生异常,资源也能正确释放
  4. 防止死锁:锁的持有时间严格限定在作用域内

扩展:更灵活的 std::unique_lock

std::unique_lock 是比 std::lock_guard 更灵活的锁管理工具,支持延迟加锁、锁的转移和定时锁等功能:

void func() {std::unique_lock<std::mutex> lock(mtx, std::defer_lock);  // 构造时不加锁// 执行一些无需锁的操作lock.lock();  // 手动加锁// 临界区lock.unlock();  // 手动解锁(可以提前释放锁)// 执行一些无需锁的操作lock.lock();  // 再次加锁// 临界区
}  // 离开作用域时,如果锁是锁定状态,则自动解锁

类似的还有微软自己提供的event 关键代码段,都是需要在各种异常退出函数是手动释放,十分繁琐,切容易遗漏。

总结

std::lock_guard 之所以能自动解锁,是因为:

  1. 它基于 RAII 模式设计
  2. 构造时获取锁,析构时释放锁
  3. C++ 保证局部对象在离开作用域时自动析构

这种设计使得锁的管理更加安全、简洁,避免了手动管理锁时常见的资源泄漏问题。

相关文章:

  • 大数据相关操作
  • BPMN.js编辑器设计器与属性面板数据交互
  • Fluent Bit持久化配置指南:保障日志不丢失的关键策略
  • uthash是一个非常轻量级的库
  • 链表的面试题8之环形链表
  • SpringBoot 商城系统高并发引起的库存超卖库存问题 乐观锁 悲观锁 抢购 商品秒杀 高并发
  • kafka入门(二)
  • Golang的文件上传与下载
  • 【北邮通信系统建模与仿真simulink笔记】(1)主要用到的模块库介绍
  • Linux:面试题
  • jenkins授权管理.
  • 界面控件DevExpress WinForms v24.2——PDF Viewer功能升级
  • 佰力博科技与您浅谈低温介电材料特性及应用分析
  • Matplotlib 高级进阶实战:多维度数据可视化组合图表
  • RK3588 IREE+Vulkan ResNet50推理测试
  • Hive drop column 的解决方法
  • Linux系统之traceroute命令详解:追踪网络路径的核心工具
  • docker常用指令总结
  • 嵌入式项目之交叉编译m2440篇
  • 深入探讨redis:哨兵模式
  • 李国英:数智化建设推动大坝实现更安全运行、更精准调度
  • 美“金穹”反导系统增加外空作战手段,外交部:中方严重关切
  • 中国原创“地贫”基因编辑疗法新进展:复旦儿科医院治愈4名重型患儿
  • 上海地铁:一孩童鞋子卡于电梯梯级处,其间未造成人员受伤
  • 印度空军为“阵风”战机换装国产导弹,以增强作战能力推动国防自主
  • 黄仁勋:美国芯片管制完全错误,阻碍别人发展只会激励他们更努力