lock_guard和unique_lock学习总结

1.std::lock_guard

std::lock_guard其实就是简单的RAII(Resource Acquisition Is Initialization)封装,资源获取即初始化。在构造函数中进行加锁,析构函数中进行解锁,这样可以保证函数退出时,锁一定被释放。

不可以对 std::lock_guard 调用 unlock 进行解锁操作。std::lock_guard 是一个非常简单的互斥量管理类,设计初衷是提供一种 RAII(资源获取即初始化)风格的锁机制,当 std::lock_guard 对象创建时锁定互斥量,并在对象销毁时析构函数里自动解锁互斥量。std::lock_guard 没有提供解锁和重新锁定 的功能。它的接口非常简单,只包含构造函数和析构函数,没有 unlocklock 方法。这使得 std::lock_guard 更加轻量级,但也更不灵活。

构造函数:

cpp 复制代码
explicit lock_guard(mutex_type& m); // 引用类型,锁定互斥量m,析构函数中解锁

// 其中mutex_type是模板参数的别名
template <class Mutex>
class lock_guard {
public:
    using mutex_type = Mutex; // 定义 mutex_type 为模板参数 Mutex
    explicit lock_guard(mutex_type& m);
    ~lock_guard();
    // ...
};

2.std::unique_lock

转自:https://www.cnblogs.com/moodlxs/p/10111843.html

std::lock_guard的功能超集, 封装了各种加锁操作,阻塞的,非阻塞的,还可以结合条件变量一起使用,基本上对锁的各种操作都封装了。所以性能和内存开销都比std::lock_guard大得多,需要有选择地使用。 std::unique_lock也会在析构的时候自动解锁,所以说,是std::lock_guard的功能超集。

支持多种加锁模式,构造函数:

cpp 复制代码
unique_lock() noexcept; // 默认构造函数创建一个不与任何互斥量相关联的 unique_lock 对象
explicit unique_lock(mutex_type& m); //创建一个与互斥量 m 相关联并立即锁定它的 unique_lock 对象,通过析构函数unlock
unique_lock( mutex_type& m, std::defer_lock_t t );   //延迟加锁,之后再调用lock()主动加锁,可以不用unlock,可以通过unique_lock的析构函数unlock
unique_lock( mutex_type& m, std::try_to_lock_t t ); //尝试加锁
unique_lock( mutex_type& m, std::adopt_lock_t t );   //马上加锁
unique_lock(unique_lock&& u) noexcept; // 移动构造函数。原来的 unique_lock 对象将不再持有互斥量。

尝试加锁例子:

cpp 复制代码
std::mutex mlock;

void work1(int& s) {
    for (int i = 1; i <= 5000; i++) {
        std::unique_lock<std::mutex> munique(mlock, std::try_to_lock);
        if (munique.owns_lock() == true) {// 判断是否加锁成功
            s += i;
        }
        else {
            // 执行一些没有共享内存的代码
        }
    }
}

延迟加锁例子:

cpp 复制代码
void work1(int& s) {
    for (int i = 1; i <= 5000; i++) {
        std::unique_lock<std::mutex> munique(mlock, std::defer_lock);
        if (munique.try_lock() == true) {// 判断当前是否能lock
            s += i;
        }
        else {
            // 处理一些没有共享内存的代码
        }
    }
}

移动构造函数例子:

cpp 复制代码
std::unique_lock<std::mutex> munique1(mlock);
std::unique_lock<std::mutex> munique2(std::move(munique1));
// 此时munique1失去mlock的权限,并指向空值,munique2获取mlock的权限
相关推荐
小bo波6 小时前
Java Swing 图形用户界面实验 —— 从算术练习到游戏开发的完整实践
java·课程设计·gui·游戏开发·扫雷·swing
咖啡八杯8 小时前
GoF设计模式——备忘录模式
java·后端·spring·设计模式
先吃饱再说11 小时前
存储的进化:从 MySQL 到浏览器缓存,数据到底住在哪?
数据库
Nturmoils11 小时前
字段太多看不全,ksql 的展开模式和输出控制怎么用
数据库·后端
Databend14 小时前
Agent 轨迹分析与归因的数据工程实践
大数据·数据库·agent
这个DBA有点耶14 小时前
SQL改写进阶:标量子查询的“隐形代价”与消除实战
数据库·mysql·架构
smallyoung15 小时前
数据库乐观锁深度解析:MySQL、PostgreSQL 实战 + Spring Boot 集成指南
数据库·mysql·postgresql
parade岁月15 小时前
MySQL JOIN解析:朴实无华但食之有味
数据库·后端
用户31693538118316 小时前
MySQL服务无法启动问题解决全记录
数据库
SamDeepThinking18 小时前
裁掉那个差程序员后,给你看团队里高手的代码:这个习惯,希望你有
java·后端·程序员