我不知道是否有可能在同一时间锁定多个互斥锁,如:锁定多个互斥锁
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
std::lock_guard
例如)解锁设备的异常安全,确保锁总是发布:
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::mutex
和boost::lock_guard
中有相似之处。
我使用pthreads,是否有可能保护我的程序免受死锁而不使用c + + 11?我正在使用pthread_mutex_lock并在.Lock()和.Unlock()函数内解锁。 – grimgrom
@grimgrom,是的。提到'lock_guard'是因为它使异常安全性更容易实现,但并不需要避免死锁。为了避免死锁,无论锁定采集之后的代码如何退出,都要始终以相同顺序获取锁并释放_always_。 – hmjd
@grimgrom,注意你可以很容易地为你的'Mutex'类编写你自己的'Lock_guard'类。只需在构造函数中使用'Lock()'和在析构函数中使用'Unlock()'。只要确保'Lock_guard'存储对'Mutex'实例的引用并且不复制它。 – hmjd
std::lock
似乎是为此目的而存在的。
使用死锁避免算法锁定给定的可锁定对象lock1,lock2,...,lockn以避免死锁。 对象被未锁定的一系列调用锁定,try_lock,unlock。如果锁定或解锁的调用导致异常,则在重新抛出之前为任何锁定的对象调用解锁。
C++ 17还提供scoped_lock
用于锁定多个互斥的特定目的,其防止死锁在RAII风格,类似于lock_guard
。
#include<mutex>
std::mutex mtx1, mtx2;
void foo()
{
std::scoped_lock lck{mtx1, mtx2};
// proceed
}
是的,这是可能的。只要小心,没有适当的努力就会很容易导致僵局。 –