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

C++ 互斥量

在 C++ 中,互斥量(std::mutex)是一种用于多线程编程中保护共享资源的机制,防止多个线程同时访问某个资源,从而避免数据竞争(data race)和不一致的问题。


🔒 一、基础用法:std::mutex

头文件:#include <mutex>

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx; // 创建一个互斥量
int counter = 0;void increment(int id) {for (int i = 0; i < 10000; ++i) {mtx.lock();       // 加锁++counter;        // 访问共享资源mtx.unlock();     // 解锁}
}

你可以通过多个线程调用 increment(),互斥量保证了线程安全。


✅ 更推荐的方式:使用 std::lock_guard

它是一种 RAII(资源获取即初始化) 的封装类,作用域结束时会自动解锁,非常安全,防止漏解锁。

void increment(int id) {for (int i = 0; i < 10000; ++i) {std::lock_guard<std::mutex> lock(mtx);++counter;} // 作用域结束时自动释放锁
}

⛔ 错误示例(不要这样做):

mtx.lock();
++counter;
// 如果中间抛异常,mutex 可能永远不会 unlock

🧠 其他互斥量类型

类型说明
std::mutex最基本的互斥量
std::recursive_mutex支持同一线程多次加锁
std::timed_mutex支持带超时的锁操作
std::shared_mutexC++17,引入读写锁(多个读一个写)

🧪 示例:多个线程安全地写输出

#include <iostream>
#include <thread>
#include <mutex>std::mutex print_mtx;void safe_print(const std::string& msg) {std::lock_guard<std::mutex> lock(print_mtx);std::cout << msg << std::endl;
}int main() {std::thread t1(safe_print, "hello from thread 1");std::thread t2(safe_print, "hello from thread 2");t1.join();t2.join();return 0;
}

try_lock()timed_mutex

if (mtx.try_lock()) {// 成功获得锁mtx.unlock();
} else {// 没拿到锁,干别的事
}
std::timed_mutex tmtx;
if (tmtx.try_lock_for(std::chrono::milliseconds(100))) {// 拿到锁tmtx.unlock();
}

总结:

方法是否推荐用法说明
mutex.lock()/unlock()❌ 不推荐(容易忘记 unlock)
std::lock_guard✅ 推荐,简单安全
std::unique_lock✅ 推荐,需要更灵活控制时
try_lock / timed_mutex✅ 用于尝试加锁或有时间要求

如你需要我帮你写一个完整的多线程例子(比如生产者-消费者模型、线程池、文件读写等),可以直接告诉我场景!

http://www.lryc.cn/news/572175.html

相关文章:

  • 【Python】python系列之函数作用域
  • 微信小程序获取指定元素,滚动页面到指定位置
  • Maven镜像
  • ssh配置sftp,实现上传下载文件
  • uni-app总结4-项目配置+HBuilder插件使用+uni插件使用
  • 正则表达式一些例子
  • 视频续播功能实现 - 断点续看从前端到 Spring Boot 后端
  • 【Bug:docker】--Docker同时部署Dify和RAGFlow出现错误
  • web3 浏览器注入 (如 MetaMask)
  • 无人机电调技术要点与突破解析!
  • 插值与模板字符串
  • 宇鹿家政服务系统小程序ThinkPHP+UniApp
  • Spring Boot 工程启动以后,我希望将数据库中已有的固定内容,打入到 Redis 缓存中,请问如何处理?
  • WEB安全--WAF的绕过思路
  • Flutter中FutureBuilder和StreamBuilder
  • 对gateway和nocas的理解
  • DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar),日历_项目里程碑示例(CalendarView01_22)
  • 局域网即时通讯软件评测:4款支持私有化部署的通讯软件对比
  • 2025 Java EasyExcel 基于Excel模板填充数据 SpringBoot+Mybatis-Flex
  • el-image在表格中显示,弹出的预览图片被遮挡,如何解决
  • 【网络空间安全】数据安全
  • 蜻蜓Q系统的技术演进:从Laravel 6到Laravel 8的升级之路-优雅草卓伊凡
  • 时序数据库概念及IoTDB特性详解
  • 若依导出模板时设置动态excel下拉框(表连接的)
  • 企微CRM系统中的任务分配与效率提升技巧
  • Mac电脑 - Sublim Text 代码编辑器
  • 大数据基础学习指南:从核心概念到技术生态全景
  • 蓝牙物联网多个核心应用场景开发与应用细化分析
  • Vue3中使用 Vue Flow 流程图方法
  • 在 Dify 平台部署一个 知识库问答(KBQA) 工作流