Check data race


"Data race" is a common but notorious issue in concurrency programs. sometimes it is difficult to debug and reproduce, especially in some big system, so this will make people very frustrated. Thankfully, the Go toolchain provides a race detector (now only works on amd64 platform.) which can help us quickly spot and fix this kind of issue, and this can save our time even lives!

Take the following classic "data race" program as an example:

package main

import (
        "fmt"
        "sync"
)

var global int
var wg sync.WaitGroup

func count() {
        defer wg.Done()
        for i := 0; i < 10000; i++{
                global++
        }
}

func main() {
        wg.Add(2)
        go count()
        go count()
        wg.Wait()
        fmt.Println(global)
}

Two tasks increase global variable simultaneously, so the final value of global is non-deterministic. Using race detector to check it:

# go run -race race.go
==================
WARNING: DATA RACE
Read by goroutine 7:
  main.count()
      /root/gocode/src/race.go:14 +0x6d

Previous write by goroutine 6:
  main.count()
      /root/gocode/src/race.go:14 +0x89

Goroutine 7 (running) created at:
  main.main()
      /root/gocode/src/race.go:21 +0x6d

Goroutine 6 (running) created at:
  main.main()
      /root/gocode/src/race.go:20 +0x55
==================
19444
Found 1 data race(s)
exit status 66

Cool! the race detector finds the issue precisely, and it also provides the detailed tips of how to modifying it. Adding the lock of writing the global variable:

package main

import (
    "fmt"
    "sync"
)

var global int
var wg sync.WaitGroup
var w sync.Mutex

func count() {
    defer wg.Done()
    for i := 0; i < 10000; i++{
        w.Lock()
        global++
        w.Unlock()
    }
}

func main() {
    wg.Add(2)
    go count()
    go count()
    wg.Wait()
    fmt.Println(global)
}  

This time, race detector is calm:

# go run -race non_race.go
20000

Please be accustomed to use this powerful tool frequently, you will appreciate it, I promise!

Reference:
Introducing the Go Race Detector.

results matching ""

    No results matching ""