gpt4 book ai didi

c++ - 该代码段中是否会发生死锁,为什么?

转载 作者:行者123 更新时间:2023-12-01 15:05:25 27 4
gpt4 key购买 nike

以下代码段中是否可能发生死锁:

void f()
{
{
std::lock_guard <std::mutex> inner (lock1);
// do something and conditionally return
}
std::lock_guard <std::mutex> outer (lock2);
// do something
}

IOW,如果多个线程调用此函数,是否会发生死锁?

我不太确定,因此将不胜感激。

最佳答案

如果重构代码以使每个作用域都是一个函数,那么很明显,锁永远不会被单个线程同时锁定:

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();
}

从中可以得出结论,当一个线程正在请求一个锁时,它不会持有一个。这使死锁变得不可能。
您可以通过创建一个 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
}

跟踪将向您显示线程将始终在请求一个锁之前释放一个锁,从而使死锁变得不可能。

如果您的代码中确实需要多个互斥锁,则应将 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
}

关于c++ - 该代码段中是否会发生死锁,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58877017/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com