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

Android常用C++特性之std::unique_lock

声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。

std::unique_lock 是 C++ 标准库中的一种灵活的锁管理类,提供了比 std::lock_guard 更多的功能和灵活性。它可以控制对互斥锁(std::mutex)的独占所有权,并允许手动锁定、解锁、尝试锁定等操作。

std::lock_guard 不同,std::unique_lock 可以:

  • 延迟锁定:允许在构造后再锁定互斥锁。
  • 提前解锁:可以在作用域内的某个时刻手动解锁互斥锁。
  • 尝试锁定:可以使用 try_lock() 方法尝试锁定互斥锁。

语法

std::unique_lock<std::mutex> lock(mutex);

std::unique_lock<std::mutex> lock(mutex, std::defer_lock); // 延迟锁定

构造函数

std::unique_lock 的构造函数有几种常用形式:

  1. 立即锁定(默认行为):

    • std::unique_lock<std::mutex> lock(mutex);
    • 创建 unique_lock 时会自动锁定传递的 mutex
  2. 延迟锁定(不锁定互斥锁):

    • std::unique_lock<std::mutex> lock(mutex, std::defer_lock);
    • 创建 unique_lock 时不会立即锁定互斥锁,你需要手动调用 lock() 来锁定。
  3. 尝试锁定(尝试立即锁定):

    • std::unique_lock<std::mutex> lock(mutex, std::try_to_lock);
    • 尝试锁定互斥锁,如果锁定失败,不会阻塞线程,可以通过 lock.owns_lock() 检查是否成功获得锁。
  4. 直接采用已有的锁定

    • std::unique_lock<std::mutex> lock(mutex, std::adopt_lock);
    • 使用此选项表明互斥锁已经被锁定,unique_lock 不会再次尝试锁定。

std::unique_lock 常用方法

  1. lock():手动锁定互斥锁。如果在构造时选择了 std::defer_lock,你可以使用 lock() 方法来在稍后锁定互斥锁。
  2. unlock():手动解锁互斥锁。你可以在需要时释放锁以允许其他线程访问共享资源。
  3. try_lock():尝试锁定互斥锁。如果锁定成功,返回 true,否则返回 false。该方法不会阻塞线程。
  4. owns_lock():返回一个布尔值,表示 unique_lock 是否拥有互斥锁的所有权。
  5. release():释放 unique_lock 对互斥锁的控制权,但不会解锁互斥锁。这在某些高级场景中可能有用。

示例

1. 基本使用
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;void printThreadId(int id) {std::unique_lock<std::mutex> lock(mtx);  // 自动锁定互斥锁std::cout << "Thread ID: " << id << std::endl;// lock 作用域结束后自动解锁
}int main() {std::thread t1(printThreadId, 1);std::thread t2(printThreadId, 2);t1.join();t2.join();return 0;
}
2. 延迟锁定
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;void work() {std::unique_lock<std::mutex> lock(mtx, std::defer_lock);  // 延迟锁定std::cout << "Before locking." << std::endl;lock.lock();  // 手动锁定std::cout << "Lock acquired." << std::endl;lock.unlock();  // 手动解锁std::cout << "Lock released." << std::endl;
}int main() {std::thread t1(work);std::thread t2(work);t1.join();t2.join();return 0;
}

在这个例子中,互斥锁在稍后通过 lock() 手动锁定,然后通过 unlock() 解锁。

3. 尝试锁定
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;void tryLockWork() {std::unique_lock<std::mutex> lock(mtx, std::try_to_lock);if (lock.owns_lock()) {std::cout << "Lock acquired by thread." << std::endl;} else {std::cout << "Failed to acquire lock." << std::endl;}
}int main() {std::thread t1(tryLockWork);std::thread t2(tryLockWork);t1.join();t2.join();return 0;
}

在这个例子中,我们使用 std::try_to_lock 尝试获取锁。如果某个线程在尝试锁定时已经锁定了互斥锁,另一个线程将无法获得锁并输出“Failed to acquire lock”。

std::unique_lockstd::lock_guard 的区别

  • 灵活性std::unique_lock 提供了更多的功能(如延迟锁定、手动解锁和尝试锁定),而 std::lock_guard 则是一个更加轻量级的加锁工具,自动加锁并在作用域结束时解锁。
  • 性能std::lock_guardstd::unique_lock 更高效,因为它是针对简单的加锁/解锁场景设计的,没有额外的操作开销。如果你只需要在构造和析构时加锁和解锁,使用 std::lock_guard 更加合适。
  • 场景:当你需要在代码的某些部分手动解锁或延迟加锁时,std::unique_lock 是更好的选择。如果你只需要简单的加锁和解锁,std::lock_guard 就足够了。

总结

  • std::unique_lock 提供了一个灵活的互斥锁管理工具,支持延迟锁定、手动解锁和尝试锁定等高级功能。
  • std::lock_guard 相比,std::unique_lock 在锁管理方面有更多的控制权,适用于更复杂的同步场景。
  • 在多线程编程中,std::unique_lock 适合那些需要在特定时刻手动锁定或解锁的场景,而 std::lock_guard 则更适合简单、固定的锁管理。

相关文章:

Android常用C++特性之std::unique_lock

声明&#xff1a;本文内容生成自ChatGPT&#xff0c;目的是为方便大家了解学习作为引用到作者的其他文章中。 std::unique_lock 是 C 标准库中的一种灵活的锁管理类&#xff0c;提供了比 std::lock_guard 更多的功能和灵活性。它可以控制对互斥锁&#xff08;std::mutex&#x…...

网络与信息安全工程师(工信部教育与考试中心)

在当今数字化时代&#xff0c;大量的敏感信息与业务流程在网络上传输和处理&#xff0c;使得网络与信息安全成为保障企业运营、政务管理以及金融交易等关键领域不可忽视的一环。 因此&#xff0c;对网络安全专家的需求日益增长。 例如&#xff0c;金融机构、大型电信运营商以…...

uni-app+vue3开发微信小程序使用本地图片渲染不出来报错[渲染层网络层错误]Failed to load local image resource

我把图片放在assets里面页面通过相对路径引入。结果一直报错。 最后我把图片放在static文件夹下面。然后修改路径指向static就可以了 或者是我们必须先import 这个图片然后在使用 import banner1 from ../../assets/images/banner/banner1.png; <image :src"banner…...

Leetcode 93-复原 IP 地址

有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址&#xff0c;但是 “0.011.255.245”、“192.168.…...

unity 中向指定的动画片段添加动画事件,并播放动画,同时获取动画片段的时长。

示例一 using UnityEngine;using System;public static class AnimationUtils{/// <summary>/// 向指定的动画片段添加动画事件&#xff0c;并播放动画&#xff0c;同时获取动画片段的时长。/// </summary>/// <param name"_animator">需要添加动画…...

JavaEE:探索网络世界的魅力——玩转UDP编程

文章目录 UDPUDP的特点UDP协议端格式校验和前置知识校验和具体是如何工作的? UDP UDP的特点 UDP传输的过程类似于寄信. 无连接: 知道对端的IP和端口号就直接进行传输,不需要建立连接.不可靠: 没有确认机制,没有重传机制,如果因为网络故障导致该段无法到达对方,UDP协议也不会…...

生成式人工智能:企业数字化转型的全新引擎,深度解析The Open Group 2024生态系统架构·可持续发展年度大会

生成式人工智能&#xff1a;企业数字化转型的全新引擎&#xff0c;深度解析The Open Group 2024生态系统架构可持续发展年度大会 随着人工智能技术的飞速发展&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;正以惊人的速度渗透到各行各业&#xff0c;成为企…...

阿里云k8s如何创建可用的api token

阿里云的 Kubernetes 配置文件&#xff08;如您所提供的 YAML 格式文件&#xff09;通常不会直接包含用于连接 Kubernetes 集群的令牌。而是包含了客户端证书和私钥数据&#xff0c;这些是用于通过证书验证而不是令牌验证的方式来与 Kubernetes API 服务器进行安全交互的。 1.…...

leetcode刷题day30|贪心算法Part04重叠区间问题(452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间)

前言&#xff1a;今天的三道题目都是重叠区间的问题。 452. 用最少数量的箭引爆气球 思路&#xff1a;局部最优&#xff1a;当气球出现重叠&#xff0c;一起射&#xff0c;所用弓箭最少&#xff1b; 全局最优&#xff1a;把所有气球射爆所用弓箭最少。 按照起始位置排序&…...

MQTT客户端实战:从连接到通信。详细说明MQTT客户端和MQTT代理进行通信

EMQX安装 EMQX服务器安装 安装文档&#xff0c;见链接不另外写 https://docs.emqx.com/zh/emqx/latest/deploy/install-ubuntu.html 启动 EMQX 启动为一个 systemd 服务&#xff1a; sudo systemctl start emqx在windows安装客户端 在线 MQTT WebSocket 客户端工具&…...

【go/方法记录】cgo静态库编译以及使用dlv定位cgo崩溃问题

目录 说在前面文件树静态库编译cgo使用崩溃模拟使用dlv定位崩溃参考 说在前面 测试环境&#xff1a;WSL2go版本&#xff1a;go version go1.23.1 linux/amd64gcc版本&#xff1a;gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0cmake版本&#xff1a;3.22.1 文件树 ├── buffer …...

(笔记自用)位运算总结+LeetCode例题:颠倒二进制位+位1的个数

一.位运算总结: 在解题之前理解一下为什么需要位运算&#xff1f;它的本质是什么&#xff1f; 力扣上不少位运算相关的题&#xff0c;并且很多题也会用到位运算的技巧。这又是为什么&#xff1f; 位运算的由来 在计算机里面&#xff0c;任何数据最终都是用数字来表示的&…...

024.PL-SQL进阶—游标

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…...

从零开始使用树莓派debian系统使用opencv4.10.0进行人脸识别(保姆级教程)

一、总体架构 本文主要是使用树莓派自带的csi摄像头&#xff0c;搭配上opencv4.10.0进行物体的识别。本文使用的环境是python3.7.3&#xff0c;环境不一样有可能安装的opencv的过程也会很不一样&#xff0c;但是python的环境我们可以自己自行安装。 二、树莓派系统的安装 本文…...

golang qq邮件发送验证码

验证码的使用场景 注册/登录&#xff1a;使用验证码可以有效减少垃圾账号注册和恶意登录&#xff1b;短信接口保护&#xff1a;高效减少防止短信接口被刷情况&#xff1b;提交/投票&#xff1a;有效减少恶意刷单、恶意提交、恶意投票等情况&#xff1b;密码找回&#xff1a;用…...

鸿蒙 OS 开发单词打卡 APP 项目实战 20240922 笔记和源码分享

配套有完整的录播课, 需要的私信. 零基础入门级别, 有点前端基础都能学会. 效果截图: 代码截图: 页面完整代码: import { AnswerStatus } from ../enums/AnswerStatus import { PracticeStatus } from ../enums/PracticeStatus import { getRandomQuestions, Question …...

力扣P1706全排列问题 很好的引入暴力 递归 回溯 dfs

代码思路是受一个洛谷题解里面大佬的启发。应该算是一个dfs和回溯的入门题目&#xff0c;很好的入门题目了下面我会先给我原题解思路我想可以很快了解这个思路。下面是我自己根据力扣大佬写的。 我会进行详细讲解并配上图辅助理解大家请往下看 #include<iostream> #inc…...

使用Python Pandas导入数据库和文件数据

大家好&#xff0c;在数据分析过程中&#xff0c;数据的导入是第一步&#xff0c;也是最重要的一步。Python的Pandas提供了强大的数据读取功能&#xff0c;支持从多种数据源导入数据&#xff0c;包括CSV、Excel、JSON、SQL数据库、网页等。Pandas库不仅能够处理常见的文件格式&…...

lef 中antenna解释

这些规则主要涉及集成电路设计中的天线效应(Antenna Effect)和通孔(Via)设计规则。 ANTENNAAREADIFFREDUCEPWL 这条规则指定了一个分段线性函数,用于根据连接到切割层的扩散区面积来计算cut_area的缩减因子。扩散区面积值应从0开始单调增加。如果没有定义此规则,PAR(mi)方程中的…...

初试Bootstrap前端框架

文章目录 一、Bootstrap概述二、Bootstrap实例1、创建网页2、编写代码3、代码说明4、浏览网页&#xff0c;查看结果5、登录按钮事件处理6、浏览网页&#xff0c;查看结果 三、实战小结 一、Bootstrap概述 大家好&#xff0c;今天我们将一起学习一个非常流行的前端框架——Boot…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...

PH热榜 | 2025-06-08

1. Thiings 标语&#xff1a;一套超过1900个免费AI生成的3D图标集合 介绍&#xff1a;Thiings是一个不断扩展的免费AI生成3D图标库&#xff0c;目前已有超过1900个图标。你可以按照主题浏览&#xff0c;生成自己的图标&#xff0c;或者下载整个图标集。所有图标都可以在个人或…...