How to explain the "deadlock" better?
Easiest way is for two different threads to try to get two locks in different orders:
thread 1:
lock(a)
lock(b)
thread2:
lock(b)
lock(a)
Assume that thread 1 gets lock A and then goes to sleep. Thread 2 gets lock B and then attempts to get lock A; since lock A is taken, thread 2 will be put to sleep until thread A is unlocked. Now thread 1 wakes back up and tries to get lock B and will be put to sleep.
For this case, there are a couple of ways to prevent it:
- A thread should never need to hold two locks simultaneously.
- If two locks must be held simultaneously, they must always be acquired in the same order (so in my example above, thread 2 would need to be modified to request lock A before requesting lock B).
Thrd 1 --- Lock A - atmpt lock on B -
\ / \
\ / \
\ / \
--- Lock A / --- wait for lock on B
Thrd 2--- Lock B - atmpt lock on A -
\ / \
\ / \
\ / \
--- Lock B / --- wait for lock on A
Thread 1 runs, Locks A, does some stuff, and gets interrupted by Thread 2 which Locks B, does some stuff and gets interrupted by Thread 1 which attempt to Lock B, but thread 2 has locked B so thread 1 waits, and is interrupted by Thread 2 which attempts to lock A, but thread 1 has lock on A so Thread 2 has to wait.
Both threads are waiting for the other thread to release a lock on a resource they are trying to get a lock on...
Deadlock
I'd rather explain it in terms totally unrelated to computers since that's often the best way to get an idea across.
I have a five-year-old son and a three-year-old daughter. Both want to do the same colouring-in book.
The daughter grabs the pencils while the son grabs the book. Neither will relinquish what they have until they get the other.
That's deadlock. It doesn't get any simpler than that.
Your processes (or children) are stuck waiting for each other and will continue waiting indefinitely until some other superior process (like Dad) comes in and breaks the deadlock.
At least with the children, you can (sometimes) get one of them to see reason and relinquish their lock. This is not usually possible with computers since the processes are not doing anything except waiting for that resource (although sometimes children enter this state as well).
Following one rule will guarantee that deadlock cannot occur:
- Have all threads of execution allocate resources in the same order.
Following some extra rules will make your threads less likely to slow each other down but keep in mind that the above rule should take precedence over all others:
- Allocate resources only when you need them.
- Release them as soon as you're finished with them.
Jack and Jill happens to want to make a sandwich at the same time. Both need a slice of bread, so they both goes to get the loaf of bread and a knife.
Jack gets the knife first, while Jill gets the loaf of bread first. Now Jack tries to find the loaf of bread and Jill tries to find the knife, but both find that what they need to finish the task is already in use. If they both decide to wait until what they need is no longer in use, they will wait for each other forever. Deadlock.