我有多个线程T1,T2,T3和T4。 T1有资源A,T2有资源B,T3有资源A,B和C,T4有资源B和C.
当T1到来时,它会锁定A并做一些工作。
然后T2来了,它锁定了B并做了一些工作。
接下来是T3,它锁定C但是正在等待A(还没有B,因为还没有获得A)。
最后T4在这里,它等待B(还没有C,因为还没有获得B)。
伪代码如下:
for all resources needed { // in case of T3, they are A and B
acquire lock on resource; // acquiring lock one after one
}
现在如果T2完成并释放B上的锁,则T4被唤醒以锁定B.但它仍然需要等待C.所以现在T4持有B并等待C。
当T1完成时发生死锁并释放A上的锁定,T3被唤醒以锁定A.但它仍然需要等待B.T3现在持有A和C并等待B.然后我有T3和T4进入无限的等待。
要解决此问题,我的伪代码更改为:
while not all resource locks obtained { // in case of T3, they are A and B
try to lock on resource; // immediate return success or fail
if fail, release all unsecured locks; // in case of T3, C is secured,
// so only A and B may be released,
// in case of T4, both B and C may be released
}
更改后的代码可以正常工作,但在我的测试中,我可以看到T3和T4不断检查锁定,整个程序由于while循环而运行得很慢。
然后我对代码做了一些小改动:
while not all resource locks obtained {
try for 1 second to lock on resource; // return after 1 second if fail
if fail, release all unsecured locks;
}
轻微的改变使锁定检查的频率降低,程序运行速度比以前快。
我不喜欢我现在所拥有的东西,因为它似乎不是最佳的,并且在达到预期效果之前效果是随机的。有没有更好的方法来解决上面提到的僵局情况,还是我应该解决现在的问题?
答案 0 :(得分:2)
防止死锁很简单:
你没有做第二次。你只是随意地试图获取锁 - 当然这是低效的。
答案 1 :(得分:1)
任何真正的死锁的解决方案是始终以相同的顺序获取锁。不需要睡觉或重试。