Reputation: 5736
I have multiple threads T1, T2, T3 and T4 for example. T1 has resource A, T2 has resource B, T3 has resource A, B and C, T4 has resource B and C.
When T1 comes, it locks on A and do some work.
Then T2 comes, it locks on B and do some work.
Next is T3, it locks on C but is waiting on A (not yet B since A is not acquired yet).
Finally T4 here, it waits for B (not yet C since B is not acquired yet).
The pseudo code is like :
for all resources needed { // in case of T3, they are A and B
acquire lock on resource; // acquiring lock one after one
}
Now if T2 finishes and releases the lock on B, T4 is waked up to lock on B. But it still needs to wait on C. So now T4 holds B and waits on C.
Deadlock occurs when T1 finishes and releases the lock on A, T3 is waked up to lock on A. But it still needs to wait on B. T3 now holds A and C and waits on B. Then I have T3 and T4 gone into an infinite wait.
To resolve this, my pseudo code changed to:
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
}
The changed code works but in my testing I could see T3 and T4 constantly checking on the locks and overall the program ran slower due to the while loop.
Then I made a small change to the code:
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;
}
The slight change made the check on locks less frequent and the program ran faster than before.
I don't like what I have at the moment because it seems not optimal and the effect is kind of random before reaching the desired result. Is there any better way to resolve the deadlock situation mentioned above or should I just settle on what I have now?
Upvotes: 1
Views: 1998
Reputation: 310850
The solution to any genuine deadlock is to always acquire the locks in the same order. No sleeps or retries required.
Upvotes: 1
Reputation: 1
Preventing deadlocks is simple:
You're not doing the second. You're just randomly trying to acquire locks - of course that's inefficient.
Upvotes: 2