At first, I know the code has some race condition , so I used "go build -race" command to check it and I want to see how the result shows, when I run, at the first time, it shows the one result as follows, and then run again shows the second one, it has two different results, and I don't know why, and is any one can tell me the reason, and how the code was executed ?, Thanks a lot very much.
Source Code:
package main
import (
"fmt"
"runtime"
"sync"
)
var (
counter int
wg sync.WaitGroup
)
func main() {
wg.Add(2)
go incCounter(1)
go incCounter(2)
wg.Wait()
fmt.Println("Final Counter:", counter)
}
func incCounter(id int) {
defer wg.Done()
for count := 0; count < 2; count++ {
value := counter
// switch goroutine
runtime.Gosched()
value++
counter = value
}
}
When I use go build -race tool to check race condition, it shows two different results ,as follows:
One Result:
==================
WARNING: DATA RACE
Write at 0x0000005fb2d0 by goroutine 7:
main.incCounter()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:34 +0x97
Previous read at 0x0000005fb2d0 by goroutine 6:
main.incCounter()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:30 +0x76
Goroutine 7 (running) created at:
main.main()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:18 +0x90
Goroutine 6 (running) created at:
main.main()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:17 +0x6f
==================
==================
WARNING: DATA RACE
Write at 0x0000005fb2d0 by goroutine 6:
main.incCounter()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:34 +0x97
Previous write at 0x0000005fb2d0 by goroutine 7:
main.incCounter()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:34 +0x97
Goroutine 6 (running) created at:
main.main()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:17 +0x6f
Goroutine 7 (running) created at:
main.main()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:18 +0x90
==================
Final Counter: 2
Found 2 data race(s)
Second Result:
==================
WARNING: DATA RACE
Read at 0x0000005fb2d0 by goroutine 7:
main.incCounter()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:30 +0x76
Previous write at 0x0000005fb2d0 by goroutine 6:
main.incCounter()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:34 +0x97
Goroutine 7 (running) created at:
main.main()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:18 +0x90
Goroutine 6 (finished) created at:
main.main()
D:/Go/projects/hello-world/src/concurrency/list7/m.go:17 +0x6f
==================
Final Counter: 4
Found 1 data race(s)
They are the two different results.
I suggest you to explore scheduling in go (good article from ardanlabs).
The short answer is you don't control an execution order, go runtime does. Each execution of the same program won’t produce the same execution trace. Race detector tracks "racy" behaviour on each run and results directly depend on the decision of the scheduler.