C++多线程如何使用互斥锁(mutex)?(代码示例)


C++多线程中mutex用于防止数据竞争,核心是加锁→访问临界区→解锁;推荐用std::lock_guard或std::unique_lock自动管理;需避免死锁(统一加锁顺序)、条件等待用std::condition_variable配合while循环检查,且注意锁粒度与性能。

在C++多线程中,mutex用于保护共享数据,防止多个线程同时访问导致数据竞争(data race)。核心是:**加锁 → 访问临界区 → 解锁**,推荐用 std::lock_guardstd::unique_lock 自动管理,避免忘记解锁或异常导致死锁。

基础用法:std::mutex + std::lock_guard

std::lock_guard 是最常用、最安全的方式——构造时自动加锁,析构时自动解锁(RAII机制),即使发生异常也不会遗漏解锁。

#include 
#include 
#include 
#include 

int counter = 0;
std::mutex mtx; // 全局互斥锁

void increment() {
    for (int i = 0; i < 100000; ++i) {
        std::lock_guard lock(mtx); // 自动加锁
        ++counter; // 临界区:仅此处访问共享变量
        // lock 析构时自动解锁(作用域结束即释放)
    }
}

int main() {
    std::vector threads;
    for (int i = 0; i < 4; ++i) {
        threads.emplace_back(increment);
    }
    for (auto& t : threads) t.join();
    std::cout << "Final counter: " << counter << "\n"; // 输出 400000
}

避免死锁:按固定顺序加锁

当一个线程需同时获取多个锁时,若不同线程以不同顺序请求锁,容易引发死锁。解决方法是统一加锁顺序,或使用 std::lock + std::adopt_lock

  • std::lock 同时锁定多个 mutex(内部使用死锁避免算法)
  • 再用 std::lock_guardstd::adopt_lock 标签接管已持锁
std::mutex mtx1, mtx2;
void transfer(int& from, int& to, int amount) {
    std::lock(mtx1, mtx2); // 安全地同时加锁
    std::lock_guard lock1(mtx1, std::defer_lock);
    std::lock_guard lock2(mtx2, std::defer_lock);
    // 更简洁写法(推荐):
    // std::lock_guard lock1(mtx1, std::adopt_lock);
    // std::lock_guard lock2(mtx2, std::adopt_lock);
    from -= amount;
    to += amount;
}

条件等待:配合 std::condition_variable

仅靠 mutex 无法实现“等待某条件成立再继续”,需搭配 std::condition_variable。注意:必须在持有对应 mutex 的前提下调用 wait

  • wait 会自动释放锁并挂起线程;条件满足被唤醒后重新获取锁
  • notify_one()notify_all() 唤醒等待线程
  • 务必用 while 循环检查条件(防止虚假唤醒)
std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void worker() {
    std::unique_lock lock(mtx);
    cv.wait(lock, []{ return ready; }); // 等待 ready == true
    std::cout << "Worker starts working...\n";
}

void notifier() {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard lock(mtx);
        ready = true;
    }
    cv.notify_one(); // 唤醒一个等待线程
}

可重入与性能提示

std::mutex 不可重入(同一线程重复 lock 会死锁),如需可重入逻辑,应改用 std::recursive_mutex(但通常说明设计有问题)。

  • 粒度要合理:锁住的代码越少越好,避免长时间持有锁阻塞其他线程
  • 避免在临界区内做耗时操作(如 I/O、网络调用、复杂计算)
  • 考虑无锁替代方案(如 std::atomic)处理简单变量读写

不复杂但容易忽略。


# ai  # c++  # ios  # stream  # 解决方法  # 一加  # 作用域  # 无锁  # 有锁  # while  # 循环  # 线程  # 多线程  # 算法  # 死锁  # 加锁  # 解锁  # 多个  # 长时间  # 越好  # 区内  # 再用  # 如需 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: PythonPandas数据分析教程_数据清洗与处理技巧  Win11如何设置开机问候语 Win11修改登录界面提示【技巧】  VSC怎样在Linux运行PHP_Ubuntu系统配置步骤【操作】  Windows11如何设置专注助手_Windows11专注助手使用攻略【技巧】  Win10电脑怎么设置网络名称_Windows10注册表NetworkList修改  如何在Golang中实现服务熔断与限流_Golang微服务容错与流控方法  Win11用户账户控制怎么关_Win11关闭UAC弹窗提示【设置】  php485在macos下怎么配置_php485 macOS系统配置指南【解答】  Win11怎么设置组合键快捷方式_Windows11自定义快捷键操作  LINUX的SELinux是什么_详解LINUX强制访问控制系统的入门与配置  Win11任务栏怎么放到顶部_Win11修改任务栏位置方法【详细】  Windows10系统怎么查看CPU核心数_Win10逻辑处理器数量查看  Mac如何将HEIC图片格式转为JPG_Mac批量转换图片【指南】  Win11麦克风没声音怎么设置_Win11麦克风权限及驱动修复【教程】  Win10任务栏天气和资讯怎么关闭 Win10禁用新闻和兴趣功能【教程】  Win10文件历史记录怎么用 Win10开启自动备份文件教程【防丢】  Win11怎么关闭右下角弹窗_Win11拦截系统通知广告【设置】  php485函数怎么捕获异常_php485错误处理机制设置技巧【操作】  php打包exe怎么传递参数_命令行参数接收方法【解答】  Windows 11怎么更改锁屏超时时间_Windows 11电源选项中设置屏幕关闭时间  Win11怎么关闭自动调节亮度 Win11禁用内容自适应亮度【设置】  Win10怎么卸载鲁大师_Win10彻底卸载鲁大师方法【步骤】  c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】  c++中如何对数组进行排序_c++数组排序算法汇总  Win10如何卸载WindowsDefender_Win10卸载Defender教程【方法】  Python生成器表达式内存优化_惰性计算说明【指导】  LINUX怎么进行文本内容搜索_Linux grep命令正则表达式用法大全【教程】  Win11怎么关闭系统推荐内容_Windows11开始菜单布局设置  Win11怎么设置麦克风权限_允许应用访问Win11麦克风【详解】  Mac的“预览”如何合并多个PDF_Mac文件处理技巧【效率】  MySQL 中使用 IF 和 CASE 实现查询字段的条件映射  如何在Mac上搭建Golang开发环境_使用Homebrew安装和管理Go版本  Windows10电脑怎么设置电源按钮_Win10按电源键关机或休眠  mac怎么安装adb_MAC配置Android ADB开发环境【详解】  php怎么操作Redis_Redis扩展连接与基本命令使用方法【方法】  Go 中 defer 在 goroutine 内部不生效的原因与执行时机详解  Win10如何关闭安全中心所有通知 Win10禁用Windows Defender提醒【设置】  Mac如何调整Dock栏大小和位置_Mac程序坞个性化设置  c# 在ASP.NET Core中管理和取消后台任务  Python函数参数高级用法_默认值与可变参数解析【教程】  PythonGIL机制理解_多线程限制解析【教程】  Win10怎么关闭自动更新错误重启 Win10策略禁止失败补丁强制重启【防护】  Win10怎样清理C盘浏览器缓存_Win10清理浏览器缓存步骤【步骤】  SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?  php控制舵机角度怎么调_php发送pwm信号控制舵机转动【解答】  c# F# 的 MailboxProcessor 和 C# 的 Actor 模型  Mac自带的词典App怎么用_Mac添加和使用多语言词典【技巧】  VSC怎样在VSC中调试PHPAPI_接口调试技巧【详解】  Win11如何更改用户账户文件夹名称 Win11修改C:Users用户名【终极教程】  Win11如何暂停系统更新 Win11暂停更新最长时限设置【步骤】 

 2026-01-05

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.