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