C++ std::unique_lock 用法
文章目录
- 1.创建 std::unique_lock 对象
- 2.自动加锁和解锁
- 3.延迟加锁与手动加解锁
- 4.尝试加锁
- 5.配合条件变量使用
- 6.小结
- 参考文献
std::unique_lock 是 C++11 提供的一个用于管理互斥锁的类,它提供了更灵活的锁管理功能,适用于各种多线程场景。
1.创建 std::unique_lock 对象
std::unique_lock<std::mutex> lock(mutex); // 创建 std::unique_lock 并关联互斥锁 mutex
你可以在构造函数中传入一个互斥锁(std::mutex 或其它互斥锁类型)来创建 std::unique_lock 对象,并且会在构造时获取互斥锁的所有权。此时,互斥锁被锁住,其他线程无法获得锁。
2.自动加锁和解锁
{std::unique_lock<std::mutex> lock(mutex); // 自动加锁// 临界区代码
} // 自动解锁
使用 std::unique_lock 创建的对象,当其生命周期结束时(通常是在大括号的作用域结束时),会自动解锁互斥锁,以确保互斥锁在不再需要时被释放。
3.延迟加锁与手动加解锁
std::unique_lock 还支持在初始化时不立即加锁,而是在需要时延迟加锁。这种特性对于一些多线程场景非常有用,允许你在获得锁之前执行一些非临界区的操作,从而减少锁的持有时间。
创建 std::unique_lock 对象时,传入互斥锁但不加锁:
std::unique_lock<std::mutex> lock(mutex, std::defer_lock);
在需要时手动加锁:
lock.lock(); // 手动加锁
// 临界区代码
lock.unlock(); // 手动解锁
你可以使用 lock() 手动加锁互斥锁,然后在互斥锁保护的临界区内执行代码,最后使用 unlock() 手动解锁互斥锁。这种方式可以让你更灵活地控制锁的生命周期。
4.尝试加锁
std::unique_lock 还提供了 try_lock() 方法,用于尝试加锁,如果锁不可用,则返回 false,如果锁成功获取,则返回 true。
std::unique_lock<std::mutex> lock(mutex, std::defer_lock);
if (lock.try_lock()) {// 锁成功获取,执行临界区代码lock.unlock();
} else {// 锁不可用,执行其他逻辑
}
5.配合条件变量使用
condition_variable(条件变量)是 C++11 中提供的一种多线程同步机制,它允许一个或多个线程等待另一个线程发出的通知,以便能够有效地进行线程同步。
条件变量(std::condition_variable)需要与 std::unique_lock 一起使用,以实现线程的等待和通知机制。
std::unique_lock<std::mutex> lck(mutex);
while (!condition) {conditionVariable.wait(lock); // 等待条件满足并释放锁
}
// 条件满足,重新获取锁并继续执行
条件变量的成员函数 wait() 会在阻塞线程的那一刻(当线程被添加到等待队列中时),函数会自动调用 lck.unlock() 释放锁,允许其他锁定的线程继续执行。
一旦收到唤醒通知(由其他线程调用 notify_one() 或 notify_all() 通知),该函数就会解除阻塞并调用 lck.lock(),使 lck 处于与调用该函数时相同的状态,然后函数返回。请注意,返回前调用 lck.lock() 加锁可能会再次阻塞线程。
为什么条件变量需要互斥锁的配合呢?
因为 condition 和等待队列都是多线程的共享资源,当访问这些共享资源时需要互斥访问。
6.小结
std::unique_lock 提供了对互斥锁更高级别的控制和灵活性,使得多线程编程更加安全和容易。在多数情况下,推荐使用 std::unique_lock 而不是直接操作互斥锁,因为它能够自动管理锁的生命周期,减少了出错的机会。
参考文献
std::unique_lock - cplusplus.com
std::condition_variable - cplusplus.com
相关文章:
C++ std::unique_lock 用法
文章目录 1.创建 std::unique_lock 对象2.自动加锁和解锁3.延迟加锁与手动加解锁4.尝试加锁5.配合条件变量使用6.小结参考文献 std::unique_lock 是 C11 提供的一个用于管理互斥锁的类,它提供了更灵活的锁管理功能,适用于各种多线程场景。 1.创建 std::u…...
Pytorch C++ 前端第二部分:输入、权重和偏差
本教程分为两部分 第 2.1 部分 – 基础知识速成课程。第 2.2 部分 – 使用 C++ 构建神经网络如果您已经了解神经网络的基础知识,那么无需阅读 Part-2.1 的内容,理解 Part-2.2 应该没有问题。我们试图通过动画 GIF 来可视化方程,从而使其简短而有趣。但请注意,我们根据在解释…...
面试题:RocketMQ 如何保证消息不丢失,如何保证消息不被重复消费?
文章目录 1、消息整体处理过程Producer发送消息阶段手段一:提供SYNC的发送消息方式,等待broker处理结果。手段二:发送消息如果失败或者超时,则重新发送。手段三:broker提供多master模式,即使某台broker宕机…...
uniapp打包安卓后在安卓屏上实现开机自启动
实现开机自启动(使用插件) 打开插件地址安卓开机自启动 Fvv-AutoStart - DCloud 插件市场 使用方法 选择你要开启自启动的项目 在项目的manifest.json中app-plus下写入以下代码 注意需要替换 android_package_name 为自己的,不然无法进行安卓apk打包 "nativePlugins&q…...
浅谈KNX总线智能照明控制系统在北京南站房中的应用
安科瑞 华楠 摘要:本文简要介绍了i-bus EIB/KNX智能建筑控制系统的基本原理及在北京南站房中的成功应用。阐述了这一系统强大的系统功能、灵活的控制方式节能效果。 关键词:i-bus智能建筑控制;控制系统;节能 1、工程概况 北京新…...
深入了解Java的核心库
掌握Java的核心库是成为一名优秀的Java开发者的关键。Java提供了丰富的核心库和API,包括集合框架、输入输出、多线程、异常处理等等。熟悉并掌握这些库的使用,可以提高编程效率和代码质量。在本文中,我们将深入讨论Java的核心库,并…...
嵌入式:驱动开发 Day9
作业:通过platform总线驱动实现 a.应用程序通过阻塞的io模型来读取number变量的值 b.number是内核驱动中的一个变量 c.number的值随着按键按下而改变(按键中断) 例如number0 按下按键number1 ,再次按下按键number0 d.在按下按键的时候需要同时…...
【ComfyUI】安装 之 window版
文章目录 序言步骤下载comfyUI配置大模型和vae下载依赖组件启动 生成图片解决办法 序言 由于stable diffusion web ui无法做到对流程进行控制,只是点击个生成按钮后,一切都交给AI来处理。但是用于生产生活是需要精细化对各个流程都要进行控制的。 故也…...
iMazing 2 .17.9最新官方中文版免费下载安装激活
iMazing 2 .17.9最新版是一款帮助用户管理IOS手机的应用程序,iMazing2最新版能力远超iTunes提供的终极的iOS设备管理器。IMazing与你的iOS设备(iPhone、 iPad或iPod)相连,使用起来非常的方便。作为苹果指定的iOS设备同步工具。 mazing什么意思 iMazing…...
Postman应用——Pre-request Script和Test Script脚本介绍
文章目录 Pre-request Script所在位置CollectionFolderRequest Test Script所在位置CollectionFolderRequest Pre-request Script(前置脚本):可以使用在Collection、Folder和Request中,并在Request请求之前执行,可用于…...
vue2中年份季度选择器(需要安装element)
调用 <!--父组件调用--><QuarterCom v-model"quart" clearable default-current/> 组件代码 <template><div><span style"margin-right: 10px">{{ label }}</span><markstyle"position:fixed;top:0;bottom:0…...
QT day5
数据库完成登入注册 mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include<QDebug> #include<QPushButton> #include<QLineEdit> #include<QLabel> #include <QMainWindow> #include<QMessageBo…...
设计模式Java实战
文章目录 一、前置1.1 目的1.2 面向对象1.3 接口和抽象类 二、七大设计原则2.1 单一职责2.2 接口隔离原则2.3 依赖倒转原则2.4 里氏替换原则2.5 开闭原则2.6 不要重复原则2.7 迪米特最少知道法则 三、23种设计模式3.1创建型:创建对象3.1.1 单例模式定义最佳实践场景…...
外国固定资产管理系统功能有哪些
很多公司都在寻找提高自己资产管理效益的方法。为了满足这一要求,国外的固定资产管理系统已经发展成多种形式。以下是国外一些常见的固定资产管理系统的特点:自动化和智能化:许多现代固定资产管理系统采用自动化和数字化技术,以简化流程,减少…...
Postman应用——控制台调试
当你在测试脚本中遇到错误或意外行为时,Postman控制台可以帮助你识别,通过将console.log调试语句与你的测试断言相结合,你可以检查http请求和响应的内容,以及变量之类的。 通常可以使用控制台日志来标记代码执行,有时…...
如何制作思维导图?
思维导图是一种非常有用的工具,可以被广泛应用于不同领域的人群。以下是一些常见的使用人群:学生、教育工作人员、各领域的专业人员,法律、商业、医学等等,创作者、艺术家、个人自我成长管理。 由此可见,思维导图可以做…...
【力扣每日一题】2023.9.21 收集树中金币
目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们一棵树,不过这棵树不是普通的树,而是无向无根树。给我们一个二维数组表示节点之间的连接关系ÿ…...
Python与数据分析--每天绘制Matplotlib库实例图片3张-第1天
目录 1.实例1--Bar color demo 2.实例2--Bar Label Demo 3.实例3--Grouped bar chart with labels 1.实例1--Bar color demo import matplotlib.pyplot as plt # 支持中文 plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus…...
pycharm 中package, directory, sources root, resources root的区别
【遇到的问题】 导入yolov5中有utils文件,自己的代码中也有utils文件,使得yolov5中的这部分引用出错了。 【解决方案】 单独建立detection文件夹,把检测相关的都放在这里,yolov5是github上拉取的源码,发现yolov5中fr…...
【谢希尔 计算机网络】第2章 物理层
目录 通信基础 基本概念 两个公式lim 奈氏准则 香农定理 奈氏准则 VS 香农定理 编码与调制 编辑 物理层下面的传输媒体 导引型传输媒体 1. 双绞线 2. 同轴电缆 3. 光缆 非导引型传输媒体 无线电微波通信 卫星通信 无线局域网使用的 ISM 频段 信道复用技术 …...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...
