锁定多个互斥锁

时间:2012-11-20 23:07:03

标签: c++ multithreading mutex

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

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

     // Code locked by mutex 1.
 }
 Mutex1.Unlock();

这对某些情况非常有用。感谢。

3 个答案:

答案 0 :(得分:33)

std::lock似乎存在于此目的。

  

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

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

答案 1 :(得分:12)

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

建议使用范围锁定和解锁工具来确保异常安全,以确保始终发布锁定(例如std::lock_guardstd::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::mutexboost::lock_guard中的提升类似。

答案 2 :(得分:10)

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

#include<mutex>

std::mutex mtx1, mtx2;
void foo()
{
    std::scoped_lock lck{mtx1, mtx2};
    // proceed
}