Essential Go Mutex  Suggest an edit

Detecting races

When you don’t use sync.Mutex to ensure exclusive access to data between goroutines or forget to lock in parts of the program, you’ll get data races.

Data races might lead to memory corruption or crashes.

Go makes it easy to instrument the code with additional checks that are very likely to catch data races.

Use -race flag to go build or go run.

Here’s a program with intentional data races.

When you run it with go run -race data_race.go the runtime will notice memory corruption.

var (
	n int

func main() {
	var wg sync.WaitGroup
	nCPU := runtime.NumCPU()
	nIter := 100
	for i := 0; i < nCPU; i++ {
		go func() {
			defer wg.Done()
			for j := 0; j < nIter; j++ {
				time.Sleep(time.Microsecond * 10)
	fmt.Printf("n is: %d, expected: %d\n", n, nCPU*nIter)
Read at 0x000001217840 by goroutine 7:
      /private/var/folders/2k/p2_4052s70vd5_cfdm0k0l740000gn/T/src658751559/main.go:26 +0x6d

Previous write at 0x000001217840 by goroutine 6:
      /private/var/folders/2k/p2_4052s70vd5_cfdm0k0l740000gn/T/src658751559/main.go:26 +0x89

Goroutine 7 (running) created at:
      /private/var/folders/2k/p2_4052s70vd5_cfdm0k0l740000gn/T/src658751559/main.go:23 +0xcd

Goroutine 6 (running) created at:
      /private/var/folders/2k/p2_4052s70vd5_cfdm0k0l740000gn/T/src658751559/main.go:23 +0xcd
n is: 548, expected: 800
Found 1 data race(s)
exit status 66

This examples shows that memory for variable n is corrupted because the final value of n is not what we expect.

It also shows that instrumentation added with -race can catch memory corruption and points out which part of program caused the corruption.

When to use -race

Additional instrumentation added by -race flag makes the program slower so it’s not usually used when compiling shipping binaries.

It’s a good idea to use on your CI (continous integration) servers when running your test suite.

  ↑ ↓ to navigate     ↵ to select     Esc to close