1.. _Lock_Pathologies: 2 3Lock Pathologies 4================ 5 6 7Locks can introduce performance and correctness problems. If you are new 8to locking, here are some of the problems to avoid: 9 10 11.. container:: section 12 13 14 .. rubric:: Deadlock 15 :class: sectiontitle 16 17 Deadlock happens when threads are trying to acquire more than one 18 lock, and each holds some of the locks the other threads need to 19 proceed. More precisely, deadlock happens when: 20 21 22 - There is a cycle of threads 23 24 25 - Each thread holds at least one lock on a mutex, and is waiting on 26 a mutex for which the *next* thread in the cycle already has a 27 lock. 28 29 30 - No thread is willing to give up its lock. 31 32 33 Think of classic gridlock at an intersection – each car has 34 "acquired" part of the road, but needs to "acquire" the road under 35 another car to get through. Two common ways to avoid deadlock are: 36 37 38 - Avoid needing to hold two locks at the same time. Break your 39 program into small actions in which each can be accomplished while 40 holding a single lock. 41 42 43 - Always acquire locks in the same order. For example, if you have 44 "outer container" and "inner container" mutexes, and need to 45 acquire a lock on one of each, you could always acquire the "outer 46 sanctum" one first. Another example is "acquire locks in 47 alphabetical order" in a situation where the locks have names. Or 48 if the locks are unnamed, acquire locks in order of the mutex’s 49 numerical addresses. 50 51 52 - Use atomic operations instead of locks. 53 54 55.. container:: section 56 57 58 .. rubric:: Convoying 59 :class: sectiontitle 60 61 Another common problem with locks is *convoying*. Convoying occurs 62 when the operating system interrupts a thread that is holding a lock. 63 All other threads must wait until the interrupted thread resumes and 64 releases the lock. Fair mutexes can make the situation even worse, 65 because if a waiting thread is interrupted, all the threads behind it 66 must wait for it to resume. 67 68 69 To minimize convoying, try to hold the lock as briefly as possible. 70 Precompute whatever you can before acquiring the lock. 71 72 73 To avoid convoying, use atomic operations instead of locks where 74 possible. 75 76