Member-only story
In the Go Language, Mutexes are Dead
Long live channels!
I’m fairly new to programming in Go, but I’ve done my fair share of systems programming in other languages like C and C++. So, I’m accustomed to the old ways of handling concurrency and preventing race conditions. Namely, I expected Mutexes (mutual exclusions, i.e. concurrency locks) to be standard practice in Go, a language known for robust patterns of parallel programming.
Not so. In fact, the Go documentation on the sync package (which provides synchronization primitives like the Mutex) advises against using them in almost all cases:
Package sync provides basic synchronization primitives such as mutual exclusion locks. Other than the Once and WaitGroup types, most are intended for use by low-level library routines. Higher-level synchronization is better done via channels and communication.
This was surprising to me. It was so surprising that, naturally, I didn’t trust it. The application I’m developing needs to prevent concurrent access to some data which gets written back to a file after every update. I figured that, since I needed to also protect data on disk, I couldn’t use Go’s memory-sharing channels, since they were only used to prevent in-memory data races.
I lost a full day to this mistake, during which I wrote unnecessarily complicated…