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

C++编程指南17 - 使用 RAII(资源获取即初始化),避免直接调用 lock()/unlock()

一:概述

      本指南的核心思想是避免手动管理锁的获取和释放,而是利用 C++ 的 RAII(Resource Acquisition Is Initialization) 机制,通过 std::unique_lockstd::lock_guard 来自动管理锁的生命周期。

     如果手动调用 lock()unlock(),很容易导致资源泄漏或死锁,因为:

  1. 代码可能在 unlock() 之前 提前返回,导致锁未释放。
  2. 代码可能在 unlock() 之前 抛出异常,导致锁未释放。
  3. 维护代码的人可能会忘记调用 unlock(),导致锁未释放。

二:错误示例

#include <mutex>

std::mutex mtx;

void do_stuff()
{
    mtx.lock();  // 手动加锁
    // ... do stuff ...
    mtx.unlock(); // 手动解锁(容易出错)
}

   出错场景1:

void do_stuff()
{
    mtx.lock();
    if (some_condition)
        return;  // 忘记 unlock(),锁永远不会释放
    mtx.unlock();
}

   出错场景2:

void do_stuff()
{
    mtx.lock();
    if (some_condition)
        throw std::runtime_error("Error occurred");  // 忘记 unlock(),锁未释放
    mtx.unlock();
}

三:解决方法

     C++ 提供了 std::lock_guardstd::unique_lock 这两个 RAII 机制的锁管理类,确保锁在作用域结束时自动释放,无需手动调用 unlock()

#include <mutex>

std::mutex mtx;

void do_stuff()
{
    std::lock_guard<std::mutex> lck(mtx);  // 构造时自动加锁,析构时自动解锁
    // ... do stuff ...
} // 离开作用域时,自动调用 unlock()
#include <mutex>

std::mutex mtx;

void do_stuff()
{
    std::unique_lock<std::mutex> lck(mtx);  // 自动加锁
    // ... do stuff ...
    lck.unlock();  // 如果需要手动释放,可以显式调用 unlock()
}


http://www.kler.cn/a/561499.html

相关文章:

  • 医疗UI的特殊法则:复杂数据可视化的“零错误”设计守则
  • DeepSeek赋能机器人革命:从推理引擎到行业落地的全栈技术实践
  • #Oracle 学习进阶路线-进阶篇:高可用、性能调优与云原生的实战突破
  • el-select滚动获取下拉数据;el-select滚动加载
  • 【云原生实战】DevOps基础与实战项目
  • 浅谈HTTP及HTTPS协议
  • 全域旅游景区导览系统:赋能智慧旅游生态,破解行业核心难题
  • AWS CLI将读取器实例添加到Amazon Aurora集群
  • AI大模型-提示工程学习笔记17—程序辅助语言模型
  • 博途V16画面管理、用户管理与文本和图形列表
  • 希尔排序:突破插入排序的局限
  • MongoDB 数据库简介
  • 什么是可重入,什么是可重入锁?它用来解决什么问题?
  • 使用DeepSeek/ChatGPT等AI工具辅助编写wireshark过滤器
  • 网卡驱动架构以及源码分析
  • 2011-2019年各省15岁及以上文盲人口数数据
  • 【redis】数据类型之Bitfields
  • conda、anaconda、pip、pytorch、tensorflow有什么区别?
  • MATLAB学习之旅:图像处理与计算机视觉应用
  • django filter 不等于