深入剖析lock_guard和unique_lock

一、lock_guard实现

template 
class lock_guard
{
public:
    using mutex_type = Mutex;

    explicit lock_guard(mutex_type& mutex) : _mutex(mutex) 
    {
        _mutex.lock();
    }

    lock_guard(mutex_type& mutex, adopt_lock_t) : _mutex(mutex) {}

    ~lock_guard()
    {
        _mutex.unlock();
    }

    lock_guard() = delete;
    lock_guard(const lock_guard&) = delete;
    lock_guard& operator=(const lock_guard&) = delete;

private:
    mutex_type& _mutex;
};

lock_guard是一个RAII封装的锁,它强制在构造期间获得锁,在析构期间释放锁。lock_guard实现了一个“mutex妈妈”模式,在构造函数中获得锁,在析构函数中释放锁。lock_guard实现简单,使用简单。

二、c++ lock_guard

c++11和之前的标准库都已经提供了lock_guard。这意味着我们可以使用std::lock_guard来保护一个操作。std::mutex(或其他互斥对象)是一个RAII类,用于管理与互斥量相关的锁。lock_guard声明一个对象并使用std::adopt_lock的参数调用构造函数,可以将这个锁的管理权交给这个对象(这就是我们在构造函数中传递的参数)。当我们在这个对象的生命周期结束时,std::lock_guard会自动释放互斥量。

#include 
#include 
#include 

std::mutex m;

void foo()
{
    std::lock_guard lock(m);
    std::cout << "Thread " << std::this_thread::get_id() << " is executing foo()\n";
}

int main()
{
    std::thread t1(foo);
    std::thread t2(foo);

    t1.join();
    t2.join();
    return 0;
}

三、std lock_guard

lock_guard是std命名空间中包含的一个类,其目的是在构造时锁定互斥锁,在析构时释放锁。std::lock_guard的作用是保护比较短的互斥锁。当有必要保护一个对象或代码段,而这个保护不会被其他代码打断时,可以使用std::lock_guard来保护。

#include 
#include 
#include 

std::mutex m;

void foo()
{
    std::lock_guard lock(m);
    std::cout << "Thread " << std::this_thread::get_id() << " is executing foo()\n";
}

int main()
{
    std::thread t1(foo);
    std::thread t2(foo);

    t1.join();
    t2.join();
    return 0;
}

四、lock_guard与unique_lock

lock_guard和unique_lock都是互斥锁的RAII封装,但它们之间的区别有哪些呢?unique_lock有更多的功能,它支持C++11标准库的move语义,可以在传递所有权时使用,而lock_guard不支持。

unique_lock还可以在已经锁定的mutex上等待信号量,可以采用不同的锁调度策略,比如超时等。

#include 
#include 
#include 

std::mutex m;

void foo()
{
    std::unique_lock lock(m);
    std::cout << "Thread " << std::this_thread::get_id() << " is executing foo()\n";
}

int main()
{
    std::thread t1(foo);
    std::thread t2(foo);

    t1.join();
    t2.join();
    return 0;
}

在上面的代码中,我们使用unique_lock创建一个std::mutex对象的锁,foo()函数获得互斥锁,并在已经获得锁的情况下执行了一段代码,这意味着即使线程被中断,它也将在互斥锁上等待。

通过这篇文章,我们详细阐述了lock_guard和unique_lock的构造函数和应用。lock_guard和unique_lock是C++11提供的两种mutex的RAII封装,是C++中保证线程安全的重要手段,很少出现锁的泄漏以及锁的锁定时间过长。对于编写安全的并发代码是极其重要的。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/293548.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-26 13:14
下一篇 2024-12-26 13:14

相关推荐

  • 深入解析Vue3 defineExpose

    Vue 3在开发过程中引入了新的API `defineExpose`。在以前的版本中,我们经常使用 `$attrs` 和` $listeners` 实现父组件与子组件之间的通信,但…

    编程 2025-04-25
  • 深入理解byte转int

    一、字节与比特 在讨论byte转int之前,我们需要了解字节和比特的概念。字节是计算机存储单位的一种,通常表示8个比特(bit),即1字节=8比特。比特是计算机中最小的数据单位,是…

    编程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什么是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一个内置小部件,它可以监测数据流(Stream)中数据的变…

    编程 2025-04-25
  • 深入探讨OpenCV版本

    OpenCV是一个用于计算机视觉应用程序的开源库。它是由英特尔公司创建的,现已由Willow Garage管理。OpenCV旨在提供一个易于使用的计算机视觉和机器学习基础架构,以实…

    编程 2025-04-25
  • 深入了解scala-maven-plugin

    一、简介 Scala-maven-plugin 是一个创造和管理 Scala 项目的maven插件,它可以自动生成基本项目结构、依赖配置、Scala文件等。使用它可以使我们专注于代…

    编程 2025-04-25
  • 深入了解LaTeX的脚注(latexfootnote)

    一、基本介绍 LaTeX作为一种排版软件,具有各种各样的功能,其中脚注(footnote)是一个十分重要的功能之一。在LaTeX中,脚注是用命令latexfootnote来实现的。…

    编程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r为前缀的字符串。r字符串中的反斜杠(\)不会被转义,而是被当作普通字符处理,这使得r字符串可以非常方便…

    编程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一个程序就是一个模块,而一个模块可以引入另一个模块,这样就形成了包。包就是有多个模块组成的一个大模块,也可以看做是一个文件夹。包可以有效地组织代码和数据…

    编程 2025-04-25
  • 深入探讨冯诺依曼原理

    一、原理概述 冯诺依曼原理,又称“存储程序控制原理”,是指计算机的程序和数据都存储在同一个存储器中,并且通过一个统一的总线来传输数据。这个原理的提出,是计算机科学发展中的重大进展,…

    编程 2025-04-25
  • 深入剖析MapStruct未生成实现类问题

    一、MapStruct简介 MapStruct是一个Java bean映射器,它通过注解和代码生成来在Java bean之间转换成本类代码,实现类型安全,简单而不失灵活。 作为一个…

    编程 2025-04-25

发表回复

登录后才能评论