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

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 提供的一个用于管理互斥锁的类&#xff0c;它提供了更灵活的锁管理功能&#xff0c;适用于各种多线程场景。 1.创建 std::u…...

Pytorch C++ 前端第二部分:输入、权重和偏差

本教程分为两部分 第 2.1 部分 – 基础知识速成课程。第 2.2 部分 – 使用 C++ 构建神经网络如果您已经了解神经网络的基础知识,那么无需阅读 Part-2.1 的内容,理解 Part-2.2 应该没有问题。我们试图通过动画 GIF 来可视化方程,从而使其简短而有趣。但请注意,我们根据在解释…...

面试题:RocketMQ 如何保证消息不丢失,如何保证消息不被重复消费?

文章目录 1、消息整体处理过程Producer发送消息阶段手段一&#xff1a;提供SYNC的发送消息方式&#xff0c;等待broker处理结果。手段二&#xff1a;发送消息如果失败或者超时&#xff0c;则重新发送。手段三&#xff1a;broker提供多master模式&#xff0c;即使某台broker宕机…...

uniapp打包安卓后在安卓屏上实现开机自启动

实现开机自启动(使用插件) 打开插件地址安卓开机自启动 Fvv-AutoStart - DCloud 插件市场 使用方法 选择你要开启自启动的项目 在项目的manifest.json中app-plus下写入以下代码 注意需要替换 android_package_name 为自己的,不然无法进行安卓apk打包 "nativePlugins&q…...

浅谈KNX总线智能照明控制系统在北京南站房中的应用

安科瑞 华楠 摘要&#xff1a;本文简要介绍了i-bus EIB/KNX智能建筑控制系统的基本原理及在北京南站房中的成功应用。阐述了这一系统强大的系统功能、灵活的控制方式节能效果。 关键词&#xff1a;i-bus智能建筑控制&#xff1b;控制系统&#xff1b;节能 1、工程概况 北京新…...

深入了解Java的核心库

掌握Java的核心库是成为一名优秀的Java开发者的关键。Java提供了丰富的核心库和API&#xff0c;包括集合框架、输入输出、多线程、异常处理等等。熟悉并掌握这些库的使用&#xff0c;可以提高编程效率和代码质量。在本文中&#xff0c;我们将深入讨论Java的核心库&#xff0c;并…...

嵌入式:驱动开发 Day9

作业&#xff1a;通过platform总线驱动实现 a.应用程序通过阻塞的io模型来读取number变量的值 b.number是内核驱动中的一个变量 c.number的值随着按键按下而改变&#xff08;按键中断&#xff09; 例如number0 按下按键number1 ,再次按下按键number0 d.在按下按键的时候需要同时…...

【ComfyUI】安装 之 window版

文章目录 序言步骤下载comfyUI配置大模型和vae下载依赖组件启动 生成图片解决办法 序言 由于stable diffusion web ui无法做到对流程进行控制&#xff0c;只是点击个生成按钮后&#xff0c;一切都交给AI来处理。但是用于生产生活是需要精细化对各个流程都要进行控制的。 故也…...

iMazing 2 .17.9最新官方中文版免费下载安装激活

iMazing 2 .17.9最新版是一款帮助用户管理IOS手机的应用程序&#xff0c;iMazing2最新版能力远超iTunes提供的终极的iOS设备管理器。IMazing与你的iOS设备(iPhone、 iPad或iPod)相连&#xff0c;使用起来非常的方便。作为苹果指定的iOS设备同步工具。 mazing什么意思 iMazing…...

Postman应用——Pre-request Script和Test Script脚本介绍

文章目录 Pre-request Script所在位置CollectionFolderRequest Test Script所在位置CollectionFolderRequest Pre-request Script&#xff08;前置脚本&#xff09;&#xff1a;可以使用在Collection、Folder和Request中&#xff0c;并在Request请求之前执行&#xff0c;可用于…...

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创建型&#xff1a;创建对象3.1.1 单例模式定义最佳实践场景…...

外国固定资产管理系统功能有哪些

很多公司都在寻找提高自己资产管理效益的方法。为了满足这一要求&#xff0c;国外的固定资产管理系统已经发展成多种形式。以下是国外一些常见的固定资产管理系统的特点:自动化和智能化:许多现代固定资产管理系统采用自动化和数字化技术&#xff0c;以简化流程&#xff0c;减少…...

Postman应用——控制台调试

当你在测试脚本中遇到错误或意外行为时&#xff0c;Postman控制台可以帮助你识别&#xff0c;通过将console.log调试语句与你的测试断言相结合&#xff0c;你可以检查http请求和响应的内容&#xff0c;以及变量之类的。 通常可以使用控制台日志来标记代码执行&#xff0c;有时…...

如何制作思维导图?

思维导图是一种非常有用的工具&#xff0c;可以被广泛应用于不同领域的人群。以下是一些常见的使用人群&#xff1a;学生、教育工作人员、各领域的专业人员&#xff0c;法律、商业、医学等等&#xff0c;创作者、艺术家、个人自我成长管理。 由此可见&#xff0c;思维导图可以做…...

【力扣每日一题】2023.9.21 收集树中金币

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一棵树&#xff0c;不过这棵树不是普通的树&#xff0c;而是无向无根树。给我们一个二维数组表示节点之间的连接关系&#xff…...

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文件&#xff0c;自己的代码中也有utils文件&#xff0c;使得yolov5中的这部分引用出错了。 【解决方案】 单独建立detection文件夹&#xff0c;把检测相关的都放在这里&#xff0c;yolov5是github上拉取的源码&#xff0c;发现yolov5中fr…...

【谢希尔 计算机网络】第2章 物理层

目录 通信基础 基本概念 两个公式lim 奈氏准则 香农定理 奈氏准则 VS 香农定理 编码与调制 ​编辑 物理层下面的传输媒体 导引型传输媒体 1. 双绞线 2. 同轴电缆 3. 光缆 非导引型传输媒体 无线电微波通信 卫星通信 无线局域网使用的 ISM 频段 信道复用技术 …...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...