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

devtools/2024/10/18 16:53:58/

声明:本文内容生成自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 则更适合简单、固定的锁管理。


http://www.ppmy.cn/devtools/119771.html

相关文章

中间件:SpringBoot集成Redis

一.Redis简介 Redis&#xff08;Remote Dictionary Server&#xff0c;远程字典服务&#xff09;是一个开源的、使用ANSI C语言编写的、支持网络交互的、可基于内存亦可持久化的日志型Key-Value数据库&#xff0c;它提供了多种语言的API。Redis通常被称为数据结构服务器&#…

如何区分这个ip是真实ip,不是虚假的ip

区分一个IP地址是真实IP还是虚假IP&#xff08;伪造IP&#xff09;是非常重要的&#xff0c;特别是在网络安全、数据采集和其他与IP相关的业务场景中。虚假IP&#xff08;也称为伪造IP或假冒IP&#xff09;可以通过多种方式被创建&#xff0c;如代理、VPN、或IP欺骗&#xff08…

灵动微高集成度电机MCU单片机

由于锂电技术的持续进步、消费者需求的演变、工具种类的革新以及应用领域的扩展&#xff0c;电动工具行业正呈现出无绳化、锂电化、大功率化、小型化、智能化和一机多能化的发展趋势。无绳化和锂电化的电动工具因其便携性和高效能的特性&#xff0c;已成为市场增长的重要驱动力…

OpenCV-指纹识别

文章目录 一、意义二、代码实现1.计算匹配点2.获取编号3.获取姓名4.主函数 三、总结 一、意义 使用OpenCV进行指纹识别是一个复杂且挑战性的任务&#xff0c;因为指纹识别通常需要高精度的特征提取和匹配算法。虽然OpenCV提供了多种图像处理和计算机视觉的工具&#xff0c;但直…

迁移学习案例-python代码

大白话 迁移学习就是用不太相同但又有一些联系的A和B数据&#xff0c;训练同一个网络。比如&#xff0c;先用A数据训练一下网络&#xff0c;然后再用B数据训练一下网络&#xff0c;那么就说最后的模型是从A迁移到B的。 迁移学习的具体形式是多种多样的&#xff0c;比如先用A训练…

git本地分支落后于远程分支,因此推送被拒绝怎么办?

error: failed to push some refs to https:// 这个错误提示表明你的本地分支落后于远程分支&#xff0c;因此推送被拒绝。你需要先将远程分支的更改合并到本地分支&#xff0c;然后再推送。 以下是解决方法&#xff1a; 拉取远程分支的更改并合并&#xff1a; git pull orig…

Linux 基本指令的学习

01. ls 指令 语法 &#xff1a; ls [ 选项 ][ 目录或文件 ] 功能 &#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息。 常用选项&#xff1a; -a 列出目录下的所有文件&#xff0c;包括以 . 开头的隐含…

P3131 [USACO16JAN] Subsequences Summing to Sevens S Python题解

[USACO16JAN] Subsequences Summing to Sevens S 题目描述 Farmer John’s N N N cows are standing in a row, as they have a tendency to do from time to time. Each cow is labeled with a distinct integer ID number so FJ can tell them apart. FJ would like to ta…