你会解释锁定顺序吗?

P-P*_*P-P 27 concurrency deadlock locking

我了解到我应该解锁逆序以锁定订单.例如.

A.lock();
B.lock();
B.unlock();
A.unlock();
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做会发生什么:

A.lock();
B.lock();
A.unlock();
B.unlock();
Run Code Online (Sandbox Code Playgroud)

我尝试制作一个死锁场景,但如果我总是先锁定A然后B,那么我不知道会发生什么样的死锁.你能帮我吗?

Adr*_*thy 42

在给出的简单情况下,不需要以相反的顺序解锁以避免死锁.

但是,随着代码变得越来越复杂,以相反的顺序解锁会帮助您保持正确的锁定顺序.

考虑:

A.lock();
B.lock();
Foo();
A.unlock();
Bar();
B.unlock();
Run Code Online (Sandbox Code Playgroud)

如果Bar()尝试重新获取A,您实际上已经破坏了锁定顺序.你拿着B然后试图得到A.现在它可以陷入僵局.

如果您以相反的顺序解锁(如果使用RAII,则非常自然):

A.lock();
B.lock();
Foo();
B.unlock();
Bar();
A.unlock();
Run Code Online (Sandbox Code Playgroud)

然后,如果Bar()尝试进行锁定并不重要,因为将保留锁定顺序.

  • 引用总是雄辩的Linus Torvalds谈到这个问题:"事实是,解锁不必完全嵌套.这是坚如磐石的*FACT*.锁定顺序很重要,解锁顺序不重要.如果你不能接受这是一个事实,然后你说"解锁订单只是为了让事情变得干净整洁",那么当你无法坚持解锁订单时,你最终会被搞砸和/或混淆.有许多完全正确的理由不要以相反的顺序解锁." http://yarchive.net/comp/linux/lock_ordering.html (2认同)
  • 我没有声称别人的答案是错的,也没有说你必须以相反的顺序解锁.我指出,以相反的顺序解锁可以更容易确保始终保持锁定顺序,即使代码发展也是如此. (2认同)

Thi*_*ilo 21

锁定顺序只是意味着您可以通过以固定顺序获取锁定来防止死锁,并且在开始解锁后不再获取锁定.

我不认为解锁的顺序在这里有任何区别(实际上,即使乱序也应该尽快释放锁定是有益的)


Don*_*eld 9

你的例子永远不会与自己陷入僵局.以相反的顺序解锁并不重要,它以一致的顺序锁定.这将是死锁,即使解锁顺序相反

Thread 1

A.lock();
B.lock();
B.unlock();
A.unlock();

Thread 2

B.lock();
A.lock();
A.unlock();
B.unlock();
Run Code Online (Sandbox Code Playgroud)