为什么使用具有唯一锁的延迟锁

Why use defer lock with unique lock

提问人:SameemSh. 提问时间:6/25/2023 更新时间:6/26/2023 访问量:81

问:

为什么要使用延迟锁定? 先获得所有权后锁定是什么? 获得所有权和锁定有点不一样。 如果我们使用互斥锁的唯一锁而不是锁定来获得所有权,它是否仍然容易出现竞争条件?

    void fun1(std::mutex &m){
        std::lock_guard<std::mutex> mlock(m);
        //multiple lines
    }

    void fun2(std::mutex &m){
        std::unique_lock<std::mutex,std::defer_lock> mlock(m);
        //multiple lines
        mlock.lock();
        //multiple lines
    }
多线程并 C++14 RAII

评论

1赞 Mat 6/25/2023
en.cppreference.com/w/cpp/thread/lock_tag 有一个例子

答:

1赞 Solomon Slow 6/25/2023 #1

如果我们拥有所有权怎么办......?

不会“获得”互斥锁的所有权:m

std::unique_lock<std::mutex,std::defer_lock> mlock(m);

实际上,它说,我现在想构造这个 RAII 对象,但我不会锁定(即“获得所有权”),直到以后。mlockmm

它还会容易受到竞争条件的影响吗?

绝对。是的。

{
    std::unique_lock<std::mutex,std::defer_lock> mlock(m);
    // Here, we still are prone to race conditions because m is not locked.
    ...
    std::lock(m);
    // Now, it's safe to use whatever data m protects.
    ...
}
// And here, m is guaranteed to be unlocked again.
...

对评论的回应,如下

使用延迟锁定的任何用例?

我能想到的唯一用例*类似于@Mat向您推荐的 cppreference 网页上显示的内容。

  1. 您想要锁定两个或多个互斥锁,并且
  2. 您希望控制互斥锁的锁定顺序,以便避免死锁,并且
  3. 您希望使用 RAII 来确保线程在不解锁所有互斥锁的情况下无法离开块。

所以,你写这样的东西:

{
    // Create RAII objects. `defer_lock` means, "Just create the objects,
    //  but don't actually lock the mutexes. I solemnly swear that
    //  that _I_ will lock them before this story ends."
    std::unique_lock<std::mutex, std::defer_lock> ulk_A(mutex_A);
    std::unique_lock<std::mutex, std::defer_lock> ulk_B(mutex_B);

    // lock both mutexes
    if (...Deadlock avoidance requires A to be locked first...) {
        std::lock(mutex_A);
        std::lock(mutex_B);
    }
    else {
        std::lock(mutex_B);
        std::lock(mutex_A);
    }
    // _Now_ it's safe to access any shared data that are protected by
    // mutex_A or mutex_B.
    ...
}
// Can't leave the block without both mutexes being unlocked again.

* 也许还有其他用途。仅仅因为*我*无法想象某件事并不意味着它不在那里等待别人想象它。

评论

0赞 SameemSh. 6/25/2023
使用延迟锁定的任何用例?
0赞 Solomon Slow 6/26/2023
@SameemSh,请参阅我更新的答案。