Seven Lessons of Difficulty That All Disappear If Nobody Shares Anything
Last timeDoing It Without a Lock
Every problem in this course needed two threads touching one piece of state. Remove the sharing and the problems do not get easier, they stop existing. Here is the price.
Removing the cause rather than managing it
Look back at the seven lessons before this one and ask what each of them
required.
The interleaving needed two threads stepping through the same state. The
non-atomic statement needed a second thread to land in the gap. The lock existed
to keep two threads out of one region. Deadlock needed two threads each holding
something the other wanted. Visibility was a question about when one thread
sees another thread's write. The ordering relation existed to answer that
question. The retry loop existed because two threads were attempting the same
location.
Every one of them is a consequence of a single decision: two threads reach the
same piece of state. Nothing in this course is a property of threads on their
own. A program with forty threads that never touch the same memory has none of
these problems, and no lock in it, and no ordering annotations, and nothing to
investigate when it misbehaves.
That is worth sitting with, because the seven lessons present a world of
techniques for managing a difficulty, and the techniques are good, and the
difficulty was optional.
| locks | lock-free | nobody shares | |
|---|---|---|---|
| bad interleavings | 1 | 1 | 0 |
| non-atomic updates | 1 | 1 | 0 |
| lock held too long | 1 | 0 | 0 |
| deadlock | 1 | 0 | 0 |
| stale reads | 1 | 1 | 0 |
| needing an ordering argu | 1 | 1 | 0 |
| starvation under content | 0 | 1 | 0 |
So the question for any concurrent design is not which technique to use. It is
whether the sharing is load-bearing, and the honest answer in a surprising
amount of code is that it is not. Two threads touch one counter because the
counter was declared at the top of the file, not because the design needed them
to.
One thread owns it
The first of the two ways to stop sharing is confinement. One thread owns a
piece of state, holds the only reference to it, and performs every operation on
it. Other threads that need something done send a request and, if they need an
answer, wait for a reply.
Nothing about the data structure changes. The same map, the same list, the same
counter, with the lock removed because there is nobody to exclude.
The lesson stops here
6 more paragraphs to go
You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.
The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.
See the planThe contentsThis is the reading half
Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.
The contents