c++ - 具有互斥量的多个锁和死锁的可能性

标签 c++ c multithreading pthreads mutex

我是线程的新手,正在尝试了解互斥体。
我将互斥体理解为仅由一个线程选取的某个对象(键)(如果它被选取,则其他线程无法选取它并且必须等待)才能访问我们要锁定的部分代码。
所以当时只有一个线程可以访问代码的锁定部分(例如共享计数器)。其他线程必须等到互斥体解锁等等。

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

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

如果我写多个互斥锁会怎样?
两个互斥锁会被同一个线程选中吗?我还读到多个互斥锁可能会导致死锁。
谁能解释并提供一个示例,说明我如何通过使用 2 个互斥锁锁定部分代码来导致死锁?

最佳答案

这是对您描述的内容进行编码的安全方法:

std::mutex Mutex1;
std::mutex Mutex2;

void
test()
{
    using namespace std;
    lock(Mutex1, Mutex2);  // no deadlock!
    lock_guard<mutex> lk1{Mutex1, adopt_lock};
    {
        lock_guard<mutex> lk2{Mutex2, adopt_lock};
        // Code locked by mutex 1 and 2.
    }   // lk2.unlock()
    // Code locked by mutex 1.
}   // lk1.unlock()

这段代码不会死锁,因为 std::lock(Mutex1, Mutex2) 锁定了两个互斥锁,同时避免了死锁(通过一些内部算法)。使用 std::lock 的一个优点是您不必记住锁定互斥量所需的顺序(这使得大型代码库中的维护更容易)。但缺点是您需要在代码中的单个点上同时锁定两个锁。如果您不能同时锁定它们,那么您必须回到其他答案所描述的顺序。

这段代码也是异常安全的,因为如果在任何地方抛出任何异常,当异常传播出去时,任何碰巧被锁定的东西都会被解锁。

关于c++ - 具有互斥量的多个锁和死锁的可能性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42720131/

相关文章:

带有 Qt 的 C++ 缓冲区

c - 对于 32 位提升的进程,OpenProcess 返回 ERROR_ACCESS_DENIED

c# - 如何在单独的线程中无休止地运行相同的方法

java - 取消 asyncTask 成本昂贵吗?

c++ - 将 DWORD_PTR 转换为类,反之亦然,无需 c 风格转换

c++ - 是否可以将调用站点上对象的静态类型用作其模板方法的自动推导模板参数?

c++ - 智能指针的 std::swap 是否保证引用不变?

c - 如何在 Eclipse IDE 上使用 Cygwin C 编译器获得正确的警告

c - 在多维数组中将聚合初始值设定项与标量初始值设定项混合

java - 如何在 Java 中等待线程完成,其中使用 run() 启动线程