C++11的加锁新方式lock_guard

引入

今天看C++11的特性发现lock_guard这个锁对象,终于不用自己再管理锁的释放和手动资源管理了

锁对象的特质

std::lock_guard属于C++11特性,锁管理遵循RAII习语管理资源
锁管理器在构造函数中自动绑定它的互斥体并加锁,在析构函数中解锁,大大减少了死锁的风险。

使用这个锁对象可以确保互斥锁将被解锁,即使发生异常,也不依赖异常处理机制来处理锁;

程序会在std::lock_guard生命周期内加锁和解锁,其中加锁和解锁分别在构造函数和析构函数中完成

基本用法

#include <iostream>
#include <mutex>
#include <thread>

class Widget{
public:
    Widget() = default;
    ~Widget() = default;

    void fun(){
        std::lock_guard<std::mutex> lock(lock_);
        std::cout << "Widget::fun run" << std::endl;
    }

private:
    std::mutex lock_;
};

void TestThread1(Widget* w){
    w->fun();
}

int main()
{
    Widget* w = new Widget();
    std::thread t1(&TestThread1, w);

    t1.join();

    return 0;
}

这个写法就是将我们的一个mutex锁放到lock_guard这个临时对象中,然后就等同于加锁了,这个锁对象会在它生命周期结束时释放锁;

好处

  • 比手动上锁不仅仅是更方便,而且使用锁对象也更加安全,它可以保证你锁的释放(即使你忘记释放了,它也会在这个函数执行完了之后释放)
  • 更容易接受异常(更不容易出现死锁的状态,每个锁都会确保将被解锁)

内部结构

template <class _Mutex>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)
lock_guard
{
public:
    typedef _Mutex mutex_type;

private:
    mutex_type& __m_;
public:

    _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY
    explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
        : __m_(__m) {__m_.lock();}

    _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY
    lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
        : __m_(__m) {}
    _LIBCPP_INLINE_VISIBILITY
    ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();}

private:
    lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE;
    lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE;
};

很明显,std::lock_guard在构造函数里调用互斥体的lock函数进行加锁,在析构函数里调用互斥体的unlock函数进行解锁。我们还可以看到std::lock_guard的拷贝构造函数和拷贝赋值运算符是私有的,因此std::lock_guard无法进行拷贝,它替我们完成了释放锁的工作(如果我们需要提前释放锁的话,只用delete这个对象)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlbertOS

还会有大爷会打钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值