Identify “Race Conditions” in Go Application

Mayur Wadekar
2 min readDec 16, 2020

Whenever application development has come across some of the things definitely came into your mind like race conditions. Race condition stated that a single resource can access at the same time by multiple threads. You can read more here about what is a race condition. So at the start of development, it is very necessary to identify that kind of thing. So the go provided a race flag to check with race conditions.

Image from Unsplash by Braden Collum

It is enough theory to know what is race condition. Let’s move to some code.

In the above code, we have added 1000 sets of goroutine which shows in line #13. After we hit the goroutines and the output we get every time different.

Using the race detector

The race detector is fully integrated with the Go toolchain. To build your code with the race detector enabled, just add the -race flag to the command line:

$ go test -race mypkg    // test the package
$ go run -race mysrc.go // compile and run the program
$ go build -race mycmd // build the command
$ go install -race mypkg // install the package

So above program we run using the following

$go run -race race_condition.go

And it will show you the output like

==================WARNING: DATA RACERead at 0x000000653300 by goroutine 8:main.increment()race_condition.go:8 +0x3aPrevious write at 0x000000653300 by goroutine 7:main.increment()race_condition.go:8 +0x56Goroutine 8 (running) created at:main.main()race_condition.go:15 +0xb0Goroutine 7 (finished) created at:main.main()race_condition.go:15 +0xb0====================================WARNING: DATA RACERead at 0x000000653300 by goroutine 9:main.increment()race_condition.go:8 +0x3aPrevious write at 0x000000653300 by goroutine 7:main.increment()race_condition.go:8 +0x56Goroutine 9 (running) created at:main.main()race_condition.go:15 +0xb0Goroutine 7 (finished) created at:main.main()race_condition.go:15 +0xb0==================final value of global=  994Found 2 data race(s)exit status 66

As you look at the error stack, that will let you know the exact line number where does it happen actually. The text created at above shows where does the exact source of race condition is. And clearly, we can see there are 2 data race conditions that have happened in the code.

And you can clearly see like read and write operation of different goroutine with the same memory location as shown below.

Read at 0x000000653300 by goroutine 9:main.increment()race_condition.go:8 +0x3aPrevious write at 0x000000653300 by goroutine 7:main.increment()race_condition.go:8 +0x56

You can avoid a race condition by adding a mutex over a critical region.

You can also explore the other commands by yourself to gain more knowledge.

Hope you’ve enjoyed the reading. :)

--

--