Concurrency

What goes wrong when more than one thing happens at once, and the machinery for making it go right. The memory model first, because every later post rests on it, then the primitives, cancellation, the named patterns, and the failure modes that give concurrency its reputation. One at a time: what the mechanism actually is, where the cost goes, the shape of problem it fits, when to reach for something else, and the Go to write it. Sister to Data Structures and Algorithms. Part of Under the Hood.

The Race Detector

A four-goroutine racy counter printed the right answer on ten runs out of ten, and the race detector failed it on the first run and exited 66. The mechanism is a vector clock per goroutine plus a bounded record of recent accesses per word, and it proves a race when two overlapping accesses have no ordering edge between them, which makes it byte-precise: adjacent bytes of one word went unreported while a one-byte overlap between two copies did not. Instrumentation measured 3.00 times the resident memory and a median 9.3 times the run time on a memory-bound loop against 2.5 times on a channel-bound one. What it never reports is the bug nobody asked it about: an atomic load followed by an atomic store returned 167,626 of 400,000 increments with no race to find.

Coming soon