C++ std::unique_lock 用法实例详解

 更新时间:2023年09月21日 15:53:23   作者:恋喵大鲤鱼  
std::unique_lock 是 C++11 提供的一个用于管理互斥锁的类,它提供了更灵活的锁管理功能,适用于各种多线程场景,这篇文章给大家介绍了C++ std::unique_lock 用法,感兴趣的朋友跟随小编一起看看吧

unique_lock 对象以独占所有权的方式( unique owership)管理 mutex 对象的上锁和解锁操作,所谓独占所有权,就是没有其他的 unique_lock 对象同时拥有某个 mutex 对象的所有权。 

在构造(或移动(move)赋值)时,unique_lock 对象需要传递一个 Mutex 对象作为它的参数,新创建的 unique_lock 对象负责传入的 Mutex 对象的上锁和解锁操作。

std::unique_lock 对象也能保证在其自身析构时它所管理的 Mutex 对象能够被正确地解锁(即使没有显式地调用 unlock 函数)。因此,和 lock_guard 一样,这也是一种简单而又安全的上锁和解锁方式,尤其是在程序抛出异常后先前已被上锁的Mutex 对象可以正确进行解锁操作,极大地简化了程序员编写与 Mutex 相关的异常处理代码

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.条件变量的配合使用

std::unique_lock 经常与条件变量(std::condition_variable)一起使用,以实现线程的等待和通知机制。当条件不满足时,std::unique_lock 可以释放锁并等待条件的发生,一旦条件满足,它可以重新获取锁并继续执行。

std::unique_lock<std::mutex> lock(mutex);
while (!condition) {
    conditionVariable.wait(lock); // 等待条件满足并释放锁
}
// 条件满足,重新获取锁并继续执行

6.小结

std::unique_lock 提供了对互斥锁更高级别的控制和灵活性,使得多线程编程更加安全和容易。在多数情况下,推荐使用 std::unique_lock 而不是直接操作互斥锁,因为它能够自动管理锁的生命周期,减少了出错的机会。

参考文献

std::unique_lock - mutex

到此这篇关于C++ std::unique_lock 用法介绍的文章就介绍到这了,更多相关C++ std::unique_lock 用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ ReSharper2021激活码永久有效

    C++ ReSharper2021激活码永久有效

    ReSharperC++是为c/c++开发者打造的一款实用Visual Studio扩展插件,这款插件旨在提升开发者的效率,今天给大家分享这款软件的激活方法,需要C++ ReSharper2021激活码的朋友参考下本文
    2021-06-06
  • 使用ShellClass获取文件属性详细信息的实现方法

    使用ShellClass获取文件属性详细信息的实现方法

    本篇文章是对ShellClass获取文件属性详细信息的实现方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 用c++实现将文本每个单词首字母转换为大写

    用c++实现将文本每个单词首字母转换为大写

    本篇文章是对用c++实现将文本每个单词首字母转换为大写的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++实现LeetCode(112.二叉树的路径和)

    C++实现LeetCode(112.二叉树的路径和)

    这篇文章主要介绍了C++实现LeetCode(112.二叉树的路径和),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C/C++程序编译流程详解

    C/C++程序编译流程详解

    C/C++程序编译过程包括下面4个阶段:1.预处理,2.编译,3.汇编,4.链接。下面我们就来详细分析下这几个阶段。
    2016-04-04
  • C语言的动态内存管理的深入了解

    C语言的动态内存管理的深入了解

    这篇文章主要为大家详细介绍了语言C的动态内存管理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • 实现C语言常用字符串库函数

    实现C语言常用字符串库函数

    这篇文章主要为大家介绍了如何实现C语言常用字符串库函数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • C++命名空间实例详解

    C++命名空间实例详解

    这篇文章主要介绍了C++命名空间实例详解,有感兴趣的同学可以研究下
    2021-02-02
  • C++ STL 序列式容器与配接器的简单使用

    C++ STL 序列式容器与配接器的简单使用

    本文主要介绍了C++ STL 序列式容器与配接器的简单使用,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2021-06-06
  • C++基础学习之函数重载的简单介绍

    C++基础学习之函数重载的简单介绍

    函数重载是一种特殊情况,C++允许在同一作用域中声明几个类似的同名函数,这些同名函数的形参列表(参数个数,类型,顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。这篇文章主要给大家介绍了关于C++基础学习之函数重载的相关资料,需要的朋友可以参考下
    2019-01-01

最新评论