Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 锁定多个互斥锁_C++_Multithreading_Mutex - Fatal编程技术网

C++ 锁定多个互斥锁

C++ 锁定多个互斥锁,c++,multithreading,mutex,C++,Multithreading,Mutex,我想知道是否可以同时锁定多个互斥锁,如: Mutex1.Lock(); { Mutex2.Lock(); { // Code locked by mutex 1 and 2. } Mutex2.Unlock(); // Code locked by mutex 1. } Mutex1.Unlock(); 在某些情况下,这将非常有用。谢谢。这是可能的,但锁定顺序必须在整个应用程序中保持一致,否则可能会导致死锁(如果两

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

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

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

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

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

建议使用范围锁定和解锁设施以确保异常安全,以确保始终释放锁(例如:

std::mutex mtx1;
std::互斥mtx2;
标准:锁紧装置mtx1锁紧装置(mtx1);
{
标准:锁紧装置mtx2锁紧装置(mtx2);
{
}
}

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

std::lock
似乎就是为了这个目的而存在的

使用死锁避免算法锁定给定的可锁定对象lock1、lock2、…、lockn以避免死锁。 对象由一系列未指定的调用锁定,尝试锁定,解锁。如果对lock或unlock的调用导致异常,则会在重新刷新之前对所有锁定的对象调用unlock


C++17还提供了
作用域锁定
,用于锁定多个互斥锁,以防止RAII样式的死锁,类似于
锁定保护

#include<mutex>

std::mutex mtx1, mtx2;
void foo()
{
    std::scoped_lock lck{mtx1, mtx2};
    // proceed
}
#包括
std::互斥mtx1,mtx2;
void foo()
{
作用域锁lck{mtx1,mtx2};
//进行
}

是的,这是可能的。只是要小心,如果没有适当的努力,这样做很容易导致死锁。我使用pthreads,不使用c++11是否可以保护我的程序免受死锁?我在.lock()和.unlock()函数中使用pthread\u mutex\u lock和unlock。@grimgrom,是的。提到了
lock\u-guard
,因为它使异常安全更容易实现,但不需要它来避免死锁。为避免死锁,请确保始终以相同的顺序获取锁并始终释放锁,而不管锁获取后的代码如何退出。@grimgrom,请注意,您可以轻松地为您的
互斥对象
类编写自己的
lock\u guard
类。只需在构造函数中使用
Lock()
,在析构函数中使用
Unlock()
。只需确保
Lock\u guard
存储对
Mutex
实例的引用,并且不复制它。如果其他地方的代码在
mtx1
之前锁定了
mtx2
,与此代码锁定同时进行
mtx1
,那么
mtx2
,那么锁卫士将不会保存您,它将死锁。两个线程将永远等待另一个家伙释放他们需要的一个。这就是这个答案的开头所提到的,但似乎已经被RAII的讨论所掩盖。死锁是多锁的主要问题。这个例子是不安全的,正如doug65536已经提到的,除非你能保证每次这些互斥锁被锁定时,它们总是以相同的顺序被锁定(祝你好运)。绝对安全的方法是使用Pubby提出的std::lock。不幸的是,目前ubuntu中默认的gcc v5.4还不支持std::scoped_lock。不过也可以使用升压模拟。
#include<mutex>

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