0
点赞
收藏
分享

微信扫一扫

unique_lock详解

犹大之窗 2022-03-12 阅读 95

unique_lock详解

  1. unique_lock取代lock_guard
    unique_lock 是一个类模板,其将一个互斥量与自身绑定,可以完全取代lock_guard
    unique_lock<mutex> myguard(mymutex) 等价于lock_guard<mutex> myguard(mymutex)
    相比于lock_guardunique_lock更加灵活,但在效率上差一点,内存占用上多一点。

  2. unique_lock的第二个参数
    adopt_lock
    示例:unique_lock<mutex> myguard(mymutex, adopt_lock)
    作用:表明互斥量mymutex 已经被lock() 上了,不会在unique_lock的构造函数中调用mymutex.lock(),因此在使用这个参数前必须将互斥量上锁。
    try_to_lock
    示例:unique_lock<mutex> myguard(mymutex, try_to_lock)
    作用:尝试去锁上互斥量mymutex,如果没有锁上也不会在此处等待,而是立刻返回,因此在使用前不能将互斥量上锁。

    void inMsgRecvQueue() {
            for (int i = 0; i < 10; ++i) {
                cout << "inMessageQueue执行,插入一个元素" << i << endl;
                unique_lock<mutex> myguard(mymutex, try_to_lock);
                //使用成员函数owns_lock()来 判断是否上锁成功
                if (myguard.owns_lock()){
                    msgRecvQueue.push_back(i);
                } else {
                    cout << "执行inMsgRecvQueue(),没拿到锁,只能干点别的" << endl;
                }
            }
        }
    

    defer_lock
    示例:unique_lock<mutex> myguard(mymutex, defer_lock)
    作用:初始化了一个没有加锁的互斥量,可以配合其成员函数灵活使用,因此在使用前不能将互斥量上锁。

    void inMsgRecvQueue() {
            for (int i = 0; i < 10; ++i) {
                cout << "inMessageQueue执行,插入一个元素" << i << endl;
                unique_lock<mutex> myguard(mymutex1, defer_lock);
                myguard.lock();
                //开始处理共享数据1
                myguard.unlock();
                myguard.lock();
                //开始处理共享数据2
                if (myguard1.owns_lock()){
                    msgRecvQueue.push_back(i);
                } else {
                    cout << "执行inMsgRecvQueue(),没拿到锁,只能干点别的" << endl;
                } 
            }
        }
    

    注意:如果在最后面给互斥量解锁了,在函数结束时,myguard 调用析构函数将不会执行mymutex.unlock()

  3. unique_lock的成员函数
    lock():给其绑定的互斥量上锁
    unlock():给其绑定的互斥量解锁
    try_lock():尝试给互斥量上锁,如果成功,返回True,否则返回False,此函数不会造成阻塞

    void inMsgRecvQueue() {
            for (int i = 0; i < 10; ++i) {
                cout << "inMessageQueue执行,插入一个元素" << i << endl;
                unique_lock<mutex> myguard(mymutex, defer_lock);
                if (myguard.try_lock()){
                    msgRecvQueue.push_back(i);
                } else {
                    cout << "执行inMsgRecvQueue(),没拿到锁,只能干点别的" << endl;
                }
            }
        }
    

    release()
    返回它所绑定的mutex对象指针,并释放所有权,此后mymutexmyguard不再有关
    如果原mutex 处于加锁状态,有责任在处理完后进行mutex.unlock() 操作

    void inMsgRecvQueue() {
            for (int i = 0; i < 10; ++i) {
                cout << "inMessageQueue执行,插入一个元素" << i << endl;
                unique_lock<mutex> myguard(mymutex);
                mutex* p = myguard.release();
                msgRecvQueue.push_back(i);
                p->unlock();
            }
        }
    
  4. unique_lock所有权的传递
    unique_lock<mutex> myguard(mymutex, defer_lock)
    当一个unique_lock与一个mutex绑定后,unique_lock就拥有了mutex的所有权
    所有权可以转移move()但不能复制,类似与智能指针unique_ptr

    void inMsgRecvQueue() {
            for (int i = 0; i < 10; ++i) {
                cout << "inMessageQueue执行,插入一个元素" << i << endl;
                unique_lock<mutex> myguard1(mymutex);
                unique_lock<mutex> myguard2(move(myguard1));
                msgRecvQueue.push_back(i);
            }
        }
    

    转移后myguard2 继承了myguard1所绑定的mutexmyguard1什么都不绑定。

举报

相关推荐

0 条评论