C++中的std::lock_guard和std::unique_lock

本文深入探讨C++中std::lock_guard与std::unique_lock的使用方法及特性。std::lock_guard是最简单的锁管理对象,构造时加锁,析构时解锁,避免了std::mutex的锁忘记问题。std::unique_lock功能更强大,提供了更多接口,如try_lock、try_lock_for等,使线程同步更为灵活。

std::lock_guard

这是最简单的一个管理锁的对象。只有构造和析构函数,在构造的时候加锁,析构的时候解锁,解锁后就不能使用该对象再加锁了。可以避免使用std::mutex时忘记解锁的情况,同时可以方便处理异常。

简单的实例:

#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <stdexcept>

std::mutex mtx;

void print_even(int n) {
    if(n % 2 == 0) {
        std::cout << n << " is even\n";
    } else {
        throw std::logic_error("not even\n");
    }
}

void print_thread_id(int id) {
    try {
    	// 在这里,try块是单独一个部分,离开块之后,锁就自动析构了
        std::lock_guard<std::mutex>lck(mtx);
        print_even(id);
    } catch(std::logic_error&) {
        std::cout << "[exception caught]\n";
    }
}

int main() {
    // 创建线程组
    std::vector<std::thread>threads;
    for(int i = 0; i < 10; ++i) {
        threads.emplace_back(std::thread(print_thread_id, i + 1));
    }
    // 所有线程等待归并
    for(auto& th : threads) {
        th.join();
    }
    return 0;
}
/*
输出结果:
[exception caught]
2 is even
[exception caught]
4 is even
[exception caught]
6 is even
[exception caught]
8 is even
[exception caught]
10 is even
*/

std::unique_lock

拥有std::lock_guard所有的功能,但是更加灵活,也有更多的接口;时间和空间要求也更高了。

给出常用的5个构造函数:

unique_lock() noexcept;                                   // (1)
explicit unique_lock (mutex_type& m);                     // (2)
unique_lock (mutex_type& m, try_to_lock_t tag);           // (3)
unique_lock (mutex_type& m, defer_lock_t tag) noexcept;   // (4)
unique_lock (mutex_type& m, adopt_lock_t tag);            // (5)
  1. 仅仅定义一个对象,不管理任何锁对象
  2. 管理锁对象m,同时尝试调用m.lock()进行加锁,如果别的unique_lock已经管理了当前锁m,那么当前线程阻塞。
  3. 管理锁对象m,如果上锁失败,线程不会阻塞
  4. 管理锁对象m,初始化的时候不会锁住m
  5. 管理锁对象m,而且m应当是一个已经被当前线程锁住的Mutex对象

常用的成员函数:

  • try_lock上锁成功返回true,否则返回false
  • try_lock_for,调用管理对象的try_lock_for函数,成功返回true,失败返回false
  • try_lock_until,同try_lock_for
  • unlock,调用管理对象的unlock函数
  • release,返回管理锁的指针,并释放管理权
  • owns_lock,判断是否拥有了锁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值