锁定多个互斥锁

Locking multiple mutexes

本文关键字:锁定      更新时间:2023-10-16

我想知道是否可以同时锁定多个互斥体,例如:

 Mutex1.Lock();
 {
     Mutex2.Lock();
     {
          // Code locked by mutex 1 and 2.
     }
     Mutex2.Unlock();
     // Code locked by mutex 1.
 }
 Mutex1.Unlock();

在某些情况下,这将非常有用。谢谢。

std::lock似乎为此目的而存在。

锁定

给定的可锁定对象 lock1, lock2, ..., 使用死锁避免算法锁定以避免死锁。 对象通过一系列未指定的调用锁定、try_lock、解锁来锁定。如果对锁定或解锁的调用导致异常,则在重新抛出之前,会为任何锁定的对象调用 lock。

http://en.cppreference.com/w/cpp/thread/lock

C++17 还提供了锁定多个互斥锁的特定目的scoped_lock,以防止 RAII 样式的死锁,类似于 lock_guard

#include<mutex>
std::mutex mtx1, mtx2;
void foo()
{
    std::scoped_lock lck{mtx1, mtx2};
    // proceed
}
这是

可能的,但锁定的顺序必须在整个应用程序中保持一致,否则可能会导致死锁(如果两个线程以相反的顺序获取锁,则每个线程可能正在等待另一个线程释放其中一个锁)。

建议使用作用域锁定和解锁功能以确保异常安全,以确保始终释放锁定(例如,std::lock_guard std::mutex):

std::mutex mtx1;
std::mutex mtx2;
std::lock_guard<std::mutex> mtx1_lock(mtx1);
{
    std::lock_guard<std::mutex> mtx2_lock(mtx2);
    {
    }
}

如果您的编译器不支持这些 C++11 功能,boost 在 boost::mutexboost::lock_guard 中具有类似的功能。