• C++11多线程编程(三)——lock_guard和unique_lock


    如果熟悉C++多线程的童鞋可能有了解到实现的互斥锁的机制还有这个写法

    lock_guard<mutex> guard(mt);

    那么这句话是什么意思呢?为什么又要搞个这样的写法呢?

    这个也是构造互斥锁的写法,就是会在lock_guard构造函数里加锁,在析构函数里解锁,之所以搞了这个写法,C++委员会的解释是防止使用mutex加锁解锁的时候,忘记解锁unlock了。

    #include <iostream>
    #include <thread>
    #include <string>
    #include <mutex>
    using namespace std;
    
    mutex mt;
    void thread_task()
    {
    for (int i = 0; i < 10; i++)
    {
    lock_guard<mutex> guard(mt);
    cout << "print thread: " << i << endl;
    }
    }
    
    int main()
    {
    thread t(thread_task);
    for (int i = 0; i > -10; i--)
    {
    lock_guard<mutex> guard(mt);
    cout << "print main: " << i << endl;
    }
    t.join();
    return 0;
    }

    这里说析构函数里解锁,那么到底什么时候调用析构函数呢?构造函数加锁我们好理解,写下这个语句的时候调用lock_guard<mutex> guard(mt),那么调用析构函数应该是大括号{}结束的时候,也就是说定义lock_guard的时候调用构造函数加锁,大括号解锁的时候调用析构函数解锁。

    虽然lock_guard挺好用的,但是有个很大的缺陷,在定义lock_guard的地方会调用构造函数加锁,在离开定义域的话lock_guard就会被销毁,调用析构函数解锁。这就产生了一个问题,如果这个定义域范围很大的话,那么锁的粒度就很大,很大程序上会影响效率。

    所以为了解决lock_guard锁的粒度过大的原因,unique_lock就出现了。

    unique_lock<mutex> unique(mt);

    这个会在构造函数加锁,然后可以利用unique.unlock()来解锁,所以当你觉得锁的粒度太多的时候,可以利用这个来解锁,而析构的时候会判断当前锁的状态来决定是否解锁,如果当前状态已经是解锁状态了,那么就不会再次解锁,而如果当前状态是加锁状态,就会自动调用unique.unlock()来解锁。而lock_guard在析构的时候一定会解锁,也没有中途解锁的功能。

    当然,方便肯定是有代价的,unique_lock内部会维护一个锁的状态,所以在效率上肯定会比lock_guard慢。

    所以,以上两种加锁解锁的方法,加上前面文章介绍的mutex方法,具体该使用哪一个,要依照具体的业务需求来决定,当然mt.lock()和mt.unlock()不管是哪种情况,是肯定都可以使用的。

    对我而言,总感觉这个lock_guard有点鸡肋而已,完全可以用mutex来替代,忘记解锁的话一般都可以通过调试发现,而且一般情况下都不会忘记。仅仅只是因为怕忘记解锁这个原因的话,真的感觉有点多此一举,徒增学习成本罢了。

    当然也许C++委员会有他们自己的考虑,对于我们而言,也只能记住就是了。

    更多精彩内容,请关注同名公众:一点月光(alittle-moon)

  • 相关阅读:
    JavaScript Eval 函数使用
    WPFToolkit Calendar & DatePicker 使用介绍
    Windows Mobile 6.5 配置环境,数据库访问,部署简单实例
    ThreadPool.QueueUserWorkItem 方法 (WaitCallback)
    Windws Mobile 6.5 Professional ADO.NET数据访问
    WPF调用Web Services
    c#中Interface的理解
    PagesSection.MaintainScrollPositionOnPostBack 属性
    EclipseRCP中文语言包版本不一致,导致导出错误
    SWT美化开源控件网站
  • 原文地址:https://www.cnblogs.com/kiwiblog/p/14167898.html
Copyright © 2020-2023  润新知