你会解释locking顺序吗?
我了解到,我应该解锁相反的顺序来locking订单。 例如。
A.lock(); B.lock(); B.unlock(); A.unlock();
但是,如果我这样做会发生什么:
A.lock(); B.lock(); A.unlock(); B.unlock();
我试图做一个死锁的情况,但如果我总是先lockingA然后B,那么我不知道会发生什么样的死锁。 你能帮我吗?
lockingsorting意味着你通过以固定顺序获得锁来防止死锁,并且在你开始解锁之后不要再获取锁。
我不认为解锁的顺序在这里有什么区别(事实上,尽快释放locking应该是有益的,即使不按顺序)
在简单的情况下,以相反的顺序解锁并不是必要的,以避免死锁。
但是 ,随着代码变得更加复杂,以相反的顺序解锁可以帮助您保持正确的locking顺序。
考虑:
A.lock(); B.lock(); Foo(); A.unlock(); Bar(); B.unlock();
如果Bar()
尝试重新获取A,那么实际上已经破坏了你的locking顺序。 你拿着B,然后试着拿A,现在可能会死锁。
如果你以相反的顺序解锁(如果你使用RAII,这是非常自然的):
A.lock(); B.lock(); Foo(); B.unlock(); Bar(); A.unlock();
那么Bar()
试图取锁就没有关系,因为locking顺序将被保留。
你的榜样不会自己陷入僵局。 以相反顺序解锁并不重要,它以一致的顺序locking。 即使解锁顺序相反,这也会导致死锁
Thread 1 A.lock(); B.lock(); B.unlock(); A.unlock(); Thread 2 B.lock(); A.lock(); A.unlock(); B.unlock();
我不认为这里会发生死锁。 一般死锁概念是一个线程等待某个资源被其他线程locking,而另一个线程则需要第一个线程locking的资源完成并释放第一个需要的资源。
进一步阅读
解锁的顺序不会影响你的系统发生死锁的容易程度,但有一个原因可以考虑解锁的顺序:
为了避免死锁,您必须确保您的locking/解锁配对,因为您永远不会错过解锁。 作为一种风格的方法,通过明显地具有负责特殊locking的代码块,更容易以视觉方式识别locking和解锁是成对的。 最终的效果是,正如你所描述的那样,明显正确的代码可能会采取和释放锁。
对于Java,如果使用synchronized
关键字进行locking,则解锁顺序相反。 无法以不同的顺序解锁使用synchronized
关键字。
synchronized(a) { synchronized(b) { // statements } }
> lock(B) > ---------- lock(C) > ---------- lock(B) >>>> would block here > ---------- release(B) > ---------- release(C) > lock(C) >>>>>> would block here > release(B) > release(C)
他们的答案很好,如果执行无序的locking和释放,另一种情况可能会发生死锁。 一句话, 无序释放和locking打破了我们用来devise我们的共享资源pipe理和关键区域的假设。