c++ std::unique_lcock 详解

news/2024/9/24 23:24:53/

std::unique_lock  C++ 标准库中的一个类,用于管理对互斥锁(std::mutex 或其派生类)的锁定和解锁。它提供了比 std::lock_guard 更灵活的控制,允许在需要时延迟锁定、提前解锁以及递归锁定等。

主要特性

  1. 延迟锁定:std::unique_lock 可以在创建时不立即锁定互斥锁,而是在稍后的时间点调用 lock() 或 try_lock() 方法来锁定。
  2. 提前解锁:通过调用 unlock() 方法,可以在不销毁 std::unique_lock 对象的情况下解锁互斥锁。这允许在锁定期间执行不需要互斥锁的操作。
  3. 所有权转移:std::unique_lock 对象可以通过移动语义(使用 std::move)来转移其所有权,从而在不释放锁的情况下将锁传递给另一个 std::unique_lock 对象。
  4. 递归锁定:如果互斥锁是可递归的(即 std::recursive_mutex),则 std::unique_lock 可以多次锁定同一个互斥锁,而不会产生死锁。
  5. 条件变量:std::unique_lock 通常与 std::condition_variable 一起使用,因为 std::condition_variable 的 wait() 方法需要一个 std::unique_lock 参数来自动解锁和重新锁定互斥锁。

使用方法

  1. 创建和锁定

std::mutex mtx;

std::unique_lock<std::mutex> lck(mtx); // 立即锁定 mtx

或者延迟锁定:

std::unique_lock<std::mutex> lck(mtx, std::defer_lock); // 不立即锁定

lck.lock(); // 稍后锁定

  1. 提前解锁

lck.unlock(); // 解锁 mtx

注意,在解锁后重新使用 lck 前,必须确保没有其他线程已经锁定了 mtx,否则可能会导致未定义的行为。

  1. 所有权转移

std::unique_lock<std::mutex> lck1(mtx);

std::unique_lock<std::mutex> lck2 = std::move(lck1); // lck1 不再拥有锁,lck2 现在拥有锁

  1. 与条件变量一起使用

std::condition_variable cv;

std::mutex mtx;

std::unique_lock<std::mutex> lck(mtx);

cv.wait(lck, []{ /* 条件检查 */ }); // 在等待期间,lck 会自动解锁和重新锁定 mtx

  1. 递归锁定(如果使用的是 std::recursive_mutex):

std::recursive_mutex rmtx;

std::unique_lock<std::recursive_mutex> rlck(rmtx);

rlck.lock(); // 可以多次锁定同一个 rmtx,不会产生死锁

注意事项

  • 不要混合使用 std::lock_guard 和 std::unique_lock 来管理同一个互斥锁,因为这可能会导致未定义的行为。
  • 在使用 std::unique_lock 时,要特别小心避免在解锁后重新使用它之前让其他线程锁定相同的互斥锁。
  • std::unique_lock 在其析构函数中会自动解锁互斥锁(除非它已经处于未锁定状态)。因此,通常不需要显式调用 unlock(),除非有特定的需求。


http://www.ppmy.cn/news/1456834.html

相关文章

./build.sh:行1: g++: 未找到命令的错误问题在centos操作系统下面如何解决

目录 g: 未找到命令报错解释g: 未找到命令解决方法题外&#xff1a;gcc和g的区别g常用命令 centos操作系统&#xff0c;执行一个bash&#xff0c;bash命令很简单&#xff0c;就是用g编译一个C的程序。报告错误&#xff1a; ./build.sh:行1: g: 未找到命令 g: 未找到命令报错解释…

Anaconda删除虚拟环境目录pkgs和envs|conda瘦身

这个文件夹里面是专门放不同环境中的包的&#xff0c;只是没有区分环境&#xff0c;都混在一起了&#xff0c; 一般在想要删除一个虚拟环境&#xff0c;除了在命令行中输入conda remove -n your_env_name(虚拟环境名称) --all 然后在envs中删除虚拟环境的文件夹&#xff0c; 还…

Node.js v20.12.2版本执行npm run dev 报openssl 错误2024最新修复方案

Node.js v20.12.2版本执行npm run dev 报openssl 错误2024最新修复方案 故障描述修复方案 故障描述 ERROR SyntaxError: missing ) after argument list C:\Users\xxx\Documents\workspace\WebstormProjects\xxxx\node_modules\webpack\lib\util\createHash.js:135return new …

巩固python1

今天做到一个随机验证码的题&#xff1a; import random as r zmb AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz r.seed(1) code for i in range(4):code r.choice(zmb) print(code)用到了random.seed方法&#xff0c;即随机种子 seed() 函数用于设置随机数生成…

docker部署nginx并配置https

1.准备SSL证书&#xff1a; 生成私钥&#xff1a;运行以下命令生成一个私钥文件。 生成证书请求&#xff08;CSR&#xff09;&#xff1a;运行以下命令生成证书请求文件。 生成自签名证书&#xff1a;使用以下命令生成自签名证书。 openssl genrsa -out example.com.key 2048 …

代码随想录35期Day31-Java

Day31题目 LeetCode122.买股票的最佳时机 核心思想&#xff1a;很简单&#xff0c;只要第二天比第一天贵&#xff0c;就第一天买入&#xff0c;第二天卖出 class Solution {public int maxProfit(int[] prices) {// 只要后一天比这一天价钱高就买&#xff0c;然后第二天卖出…

phpstudy 搭建 upload-labs 文件上传靶场

phpstudy 搭建靶场&#xff1a;下载安装好phpstudy后&#xff0c;下载靶场源码&#xff1a; upload-labs下载地址&#xff1a; https://github.com/c0ny1/upload-labs 下载完压缩文件&#xff0c;解压文件&#xff0c;解压后的文件夹命名为upload--labs 将解压后到文件夹放…

【牛客】Tokitsukaze and Average of Substring

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 前缀和。 开一个int类型的前缀和数组pre[30][N]&#xff08;pre[i][j]表示某字符转成的数字 i 在一段区间的前缀个数。因为字母表有‘a’~z…