Code Path 1 Code Path 2 mutex_enter(&A); mutex_enter(&B); ... ... mutex_enter(&B); mutex_enter(&A); ... ... mutex_exit(&B); mutex_exit(&A); ... ... mutex_exit(&A); mutex_exit(&B);
If thread 1 is executing code path one, and thread two is executing code path 2, the following could occur:
Thread one acquires mutex A.
Thread two acquires mutex B.
Thread one needs mutex B, so it blocks holding mutex A.
Thread two needs mutex A, so it blocks holding mutex B.
These threads are now deadlocked. This is hard to track, particularly since the code paths are rarely so straightforward. Also, it doesn't always happen, as it depends on the relative timing of threads 1 and 2.