新闻中心

C++ mutex互斥锁怎么用_C++ lock_guard与unique_lock加锁教程

2025-11-28
浏览次数:
返回列表
C++多线程中,mutex用于保护共享数据,避免数据竞争。推荐使用RAII机制的std::lock_guard进行自动加锁解锁,确保异常安全;若需延迟加锁或配合条件变量,则使用更灵活的std::unique_lock;仅在简单场景下使用std::mutex的lock/unlock,但易因异常导致死锁,不推荐手动管理。

c++ mutex互斥锁怎么用_c++ lock_guard与unique_lock加锁教程

在C++多线程编程中,mutex(互斥锁)是保护共享数据、防止多个线程同时访问的关键工具。为了避免数据竞争,我们需要对临界区进行加锁。C++标准库提供了几种方便的机制来管理锁,包括直接使用std::mutex配合lock()/unlock(),以及更安全的RAII风格的std::lock_guardstd::unique_lock

std::mutex 基本用法

std::mutex是最基本的互斥量类型,它提供lock()unlock()成员函数。

注意:不建议手动调用lock/unlock,容易因异常或提前return导致死锁。

示例:

#include <thread>
#include <mutex>
#include <iostream>

std::mutex mtx;
int shared_data = 0;

void unsafe_increment() {
    mtx.lock();  // 手动加锁
    ++shared_data;
    std::cout << "Value: " << shared_data << std::endl;
    mtx.unlock(); // 手动解锁
}

int main() {
    std::thread t1(unsafe_increment);
    std::thread t2(unsafe_increment);
    t1.join();
    t2.join();
    return 0;
}

std::lock_guard 自动加锁(推荐基础用法)

std::lock_guard是一个RAII(资源获取即初始化)类,在构造时自动加锁,析构时自动解锁。即使代码抛出异常,也能保证锁被释放。

适用于简单的、作用域明确的加锁场景。

修改上面的例子:

#include <thread>
#include <mutex>
#include <iostream>

std::mutex mtx;
int shared_data = 0;

void safe_increment() {
    std::lock_guard<std::mutex> guard(mtx); // 构造即加锁
    ++shared_data;
    std::cout << "Value: " << shared_data << std::endl;
} // guard离开作用域,自动解锁

int main() {
    std::thread t1(safe_increment);
    std::thread t2(safe_increment);
    t1.join();
    t2.join();
    return 0;
}

std::unique_lock 更灵活的锁管理

std::unique_locklock_guard更灵活,支持延迟加锁、条件变量、可移动、运行时选择是否加锁等特性。

N世界 N世界

一分钟搭建会展元宇宙

N世界 138 查看详情 N世界

常见用途:

  • 配合std::condition_variable使用
  • 需要在某个条件下才加
  • 需要临时释放锁再重新获取

示例:延迟加锁与作用域控制

#include <thread>
#include <mutex>
#include <iostream>

std::mutex mtx;
int shared_data = 0;

void complex_operation() {
    std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // 不立即加锁

    // 做一些不需要锁的操作
    std::cout << "Preparing..." << std::endl;

    // 需要访问共享数据时再加锁
    lock.lock();
    ++shared_data;
    std::cout << "Value: " << shared_data << std::endl;
    // lock.unlock(); 可以手动释放
} // 离开作用域自动释放(如果还持有)

int main() {
    std::thread t1(complex_operation);
    std::thread t2(complex_operation);
    t1.join();
    t2.join();
    return 0;
}

如何选择:lock_guard vs unique_lock

基本原则:

  • 如果只是简单地在作用域内加锁,用std::lock_guard —— 更轻量、高效
  • 如果需要延迟加锁、条件变量、或中途释放锁,用std::unique_lock

性能上lock_guard略优,因为它不支持移动、也不保存“是否已加锁”的状态,而unique_lock有轻微开销。

基本上就这些。掌握这三种方式,就能写出安全又高效的C++多线程代码。关键是优先使用RAII封装,避免手动管理锁。

以上就是C++ mutex互斥锁怎么用_C++ lock_guard与unique_lock加锁教程的详细内容,更多请关注其它相关文章!


# 更灵活  # 四平抖音付费营销推广  # 网站推广计划书app  # 潍坊线下门店seo报价  # seo关键词500报告  # 网站推广执行方案步骤  # 新乡360seo优化  # 怀柔企业网站建设排名  # 咸阳抖音seo推广  # seo标题举例  # 夹江移动网站建设  # 是一个  # 有什么区别  # 如何使用  # 工具  # 互斥  # 解锁  # 如何实现  # 死锁  # 多线程  # 加锁  # red  # 标准库  # 作用域  # stream  # ios  # c++  # ai 


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


相关推荐: 优化LangChain文档加载与ChromaDB集成:解决多文档处理与分块问题  Win11怎么修改默认浏览器_Windows 11设置Chrome为默认  Win10怎么设置静态IP地址 Win10手动配置IP地址步骤【指南】  1688商家版怎样分析买家画像精准供货_1688商家版分析买家画像精准供货【供货策略】  怎么在mac上运行html代码_mac运行html代码方法【指南】  抖音网页版快捷访问 抖音网页版网页版入口操作教程  深入理解Go语言中的指针类型:以*string为例  QQ邮箱网页版入口 QQ邮箱官方邮箱登录通道  mysql密码锁定怎么解锁_mysql密码锁定解锁后修改密码步骤  如何在离线环境中使用Composer_Composer离线安装依赖包的技巧与策略  腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程  TikTok评论显示延迟如何处理 TikTok评论刷新优化方法  高德地图沿途添加点失败如何解决 高德多点规划方法  Node.js CSV 数据处理:基于字段空值条件过滤整条记录的策略  sublime侧边栏怎么增强功能_SideBarEnhancements for sublime安装与配置  excel如何生成目录 excel一键生成工作表目录超链接  PHP中SSG-WSG API的AES加密实践:正确使用初始化向量  痛风发作了怎么办? 快速止痛和后期饮食调理  Win10如何清理注册表垃圾 Win10注册表维护与优化指南【慎用】  Composer的 "conflict" 字段有什么用_如何声明不兼容的包以避免依赖冲突  一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法  Yandex官网搜索引擎免登录_俄罗斯Yandex一键直达入口  邮政快递单号查询入口 邮政快递物流信息在线查询入口  vivo手机参数配置怎么增强信号_vivo手机参数配置信号增强方法  Highcharts 雷达图径向轴标签定制指南:利用多Y轴实现数值标注  Lar*el 递归关系中排除指定分支的教程  steam官方入口大全 steam账号注册及操作指南  知音漫客正版漫画平台_知音漫客官网账号登录  Windows7怎么硬盘安装 Windows7提取ISO镜像到非系统盘并运行setup.exe实现硬盘直装【教程】  Win10磁盘清理工具在哪 Win10打开并使用磁盘清理【教程】  冬*霸灯泡不亮怎么办_浴霸取暖灯一盏不亮的灯座清洁修复法  谷歌推RCS信息存档功能:公司可监控员工私密信息!  Go语言中高效处理x-www-form-urlencoded表单数据  J*aScript中高效清空DOM列表元素:解决for循环中断与任务管理问题  PS5 Pro有点优势但不多! 《燕云十六声》PS5平台与PC性能画面对比  b站怎么删除评论_b站评论管理与删除操作  Pandas DataFrame 高效批量赋值:告别循环与笛卡尔积误区  文心一言怎样用批量生成做多版文案_文心一言用批量生成做多版文案【批量创作】  漫蛙2(台版)官方入口地址 漫蛙2(台版)正版漫画网页端  外媒分析《GTA6》定价:卖100美元可以但真没必要!  Node.js 中使用 node-cron 实现定时 API 数据抓取与处理  LINQ to XML为何解析失败? 深入理解C# XDocument的异常处理  J*aScript中安全有效地处理localStorage字符串数据  高德地图总提示网络异常怎么办 高德地图离线导航设置与网络排查方法  地铁跑酷免费秒玩入口链接 地铁跑酷小游戏免费秒玩网站  铃兰之剑为这和平的世界希里技能组及加点推荐  构建轻量级网站内部消息系统:Formspree 集成指南  Lar*el DB::listen 事件中的查询执行时间单位解析  Go语言中JSON数据解析与字段访问教程  蛙漫正版漫画平台入口_蛙漫免费阅读全站漫画资源 

搜索