Golang - Why does this race condition occur?

package main
import "fmt"

var quit chan int
var glo int

func test() {
    fmt.Println(glo)
}

func main() {
    glo = 0
    n := 10000
    quit = make(chan int, n)
    go test()
    for {
        quit <- 1
        glo++
    }
}

Situation:

The above program outputs 10000. But when I assign a bigger number to n (e.g. n := 1000000), the output will be a random number less than n.

I haven't called runtime.GOMAXPROCS(), so these two goroutines can't run in parallel. Executing go run -race to detect race conditions, ends up without any warnings.

Question:

Why does this race condition occur?

Answers


As there is no synchronisation between the main and test goroutines, you don't know at what point the fmt.Println call in test will happen.

When running with GOMAXPROCS = 1, the answer will essentially depend on when the scheduler decides to stop executing main and switch to test. The send operation within the loop is one point where the scheduler can switch over to another goroutine, so with enough iterations of the loop you'd expect test to get a chance to execute at some point. It isn't necessarily going to switch at the same iteration every run leading to the variation in results.

As for catching this with the race detector, it successfully catches the problem for me:

$ go run -race test.go
==================
WARNING: DATA RACE
Read by goroutine 5:
  main.test()
      /../test.go:8 +0x6e

Previous write by main goroutine:
  main.main()
      /.../test.go:18 +0xfe

Goroutine 5 (running) created at:
  main.main()
      /.../test.go:15 +0x8f
==================
...

Need Your Help

Spatialite for Android NDK Build

android android-ndk cygwin spatialite geos

I am having a little trouble with build an existing project at:

GoSublime go to definition

go sublimetext2

Does go to definition work in GoSublime 2 or 3 ?