Go: Mutex and Starvation

A Journey With Go
Published in
6 min readSep 13, 2019


Illustration created for “A Journey With Go”, made from the original Go Gopher, created by Renee French.

ℹ️ This article is based on Go 1.13.

While developing in Golang, a mutex can encounter starvation issues when it consistently tries to acquire a lock that it is never able to get. For this article, we’ll look at a starvation issue affecting Go 1.8 that was solved in Go 1.9.


In order to illustrate a starvation situation with a mutex, I will take the example made by Russ Cox about the issue in which they discuss mutex improvement:

This example is based on two goroutines:

  • goroutine 1 holds the lock for a long time and briefly releases it
  • goroutine 2 briefly holds the lock and releases it for a long time

Both have a cycle of 100 microseconds, but since goroutine 1 is constantly requesting the lock, we could expect it will get the lock more often.

Here is an example, done with Go 1.8, of the lock distribution with a loop of 10 iterations:

Lock acquired per goroutine:
g1: 7200216
g2: 10

The mutex has been acquired ten times by the second goroutine, while the first one got it more than seven million times. Let’s analyze what is happening here.

First, goroutine 1 will get the lock and sleep for 100 microseconds. When goroutine 2 tries to acquire the lock, it will be added to the lock’s queue — FIFO order — and the goroutine will go into waiting:

Figure 1 — lock acquisition

Then, when goroutine 1 finishes its work, it will release the lock. This release will notify the queue to wake goroutine 2 up. Goroutine 2 will be marked as runnable and is waiting for the Go Scheduler to be run on a thread: