Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Would you explain lock ordering?

I learned that I should unlock reverse order to lock order. For example.

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

But, what happen if I did like this :

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

I try to make a deadlock scenario, but if I always lock A earlier then B, then I don't know how deadlock would happen. Would you help me?

like image 773
P-P Avatar asked Dec 23 '09 07:12

P-P


3 Answers

In the simple case given, unlocking in the reverse order is not necessary to avoid a deadlock.

However, as the code gets more complicated, unlocking in the reverse order helps you maintain proper lock ordering.

Consider:

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

If Bar() attempts to reacquire A, you've effectively broken your lock ordering. You're holding B and then trying to get A. Now it can deadlock.

If you unlock in the reverse order style (which is very natural if you use RAII):

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

then it doesn't matter if Bar() attempts to take a lock, as lock ordering will be preserved.

like image 131
Adrian McCarthy Avatar answered Sep 28 '22 07:09

Adrian McCarthy


Lock ordering just means that you prevent deadlocks by obtaining locks in a fixed order, and do not obtain locks again after you start unlocking.

I do not think the order of unlocks makes any difference here (in fact, it should be beneficial to release a lock as soon as possible, even if out of order)

like image 35
Thilo Avatar answered Sep 28 '22 06:09

Thilo


Your example isn't going to deadlock with itself ever. Unlocking in reverse order isn't important, it's locking in a consistent order. This will dead lock, even though unlocks are in reverse order

Thread 1

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

Thread 2

B.lock();
A.lock();
A.unlock();
B.unlock();
like image 43
Don Neufeld Avatar answered Sep 28 '22 06:09

Don Neufeld