Is deadlock possible in the following code snippet:
void f()
{
{
std::lock_guard <std::mutex> inner (lock1);
// do something and conditionally return
}
std::lock_guard <std::mutex> outer (lock2);
// do something
}
Run Code Online (Sandbox Code Playgroud)
IOW, if multiple threads call this function, can a deadlock occur?
I am not too sure so any help would be highly appreciated.
If you refactor your code so each scope is a function, it become clears that the locks are never locked at the same time by a single thread :
std::mutex lock1;
std::mutex lock2;
// One mutex in g => No deadlock possible
void g()
{
std::lock_guard <std::mutex> inner (lock1);
// do something
}
// One mutex in h => No deadlock possible
void h()
{
std::lock_guard <std::mutex> outer (lock2);
// do something
}
// No mutex in f => No deadlock possible
void f()
{
g();
h();
}
Run Code Online (Sandbox Code Playgroud)
从中可以得出结论,当一个线程正在请求一个锁时,它不会持有一个。这使死锁变得不可能。您可以通过创建一个BasicLockable对象来自己检查这一点,该对象只需包装std::mutex并添加跟踪即可:
class PrinterMutex {
public:
PrinterMutex(const std::string& _name) : name(_name) {}
~PrinterMutex() {}
void lock() {
std::cout << "lock : " << name << std::endl;
m.lock();
}
void unlock() {
std::cout << "unlock : " << name << std::endl;
m.unlock();
}
private:
std::mutex m;
std::string name;
};
PrinterMutex lock1("lock1");
PrinterMutex lock2("lock2");
int main()
{
{
std::lock_guard <PrinterMutex> inner (lock1);
// do something and conditionally return
}
std::lock_guard <PrinterMutex> outer (lock2);
// do something
}
Run Code Online (Sandbox Code Playgroud)
跟踪将向您显示线程将始终在请求一个锁之前释放一个锁,从而使死锁变得不可能。
如果您的代码中确实需要多个互斥锁,则应使用std::lock多个Lockable对象通过避免死锁算法锁定互斥锁。
std::mutex lock1;
std::mutex lock2;
void g()
{
std::lock(lock1, lock2);
std::lock_guard<std::mutex> inner (lock1, std::adopt_lock);
std::lock_guard<std::mutex> outer (lock2, std::adopt_lock);
// Do something
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |