1. 程式人生 > >Go race condition以及解決方法

Go race condition以及解決方法

形成條件

一般情況下是由於在沒有加鎖的情況下多個協程進行操作對同一個變數操作形成競爭條件.

如果沒有鎖的情況會輸出結果非1001.


func main()  {
	c := 1
	g := sync.WaitGroup{}
	times := 1000
	for i:=0 ; i< times; i++ {
		g.Add(1)
		go func() {
			c++
			g.Done()
		}()
	}
	g.Wait()
	fmt.Println(c)
}

原因

多核CPU操作同一變數,可能會取到’舊’的值,是一個併發導致的錯誤.

檢查方式

對專案執行競爭檢測:

$ 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

可以輕鬆的看到問題程式碼:

$ go run -race mtest.go

==================
WARNING: DATA RACE
Read at 0x00c0420080e0 by goroutine 7:
  main.main.func1()
      C:/Users/liuzexin/go/src/gotest/mtest.go:65 +0x42

Previous write at 0x00c0420080e0 by goroutine 6:
  main.main.func1()
      C:/Users/liuzexin/go/src/gotest/mtest.go:65 +0x5b

Goroutine 7 (running) created at:
  main.main()
      C:/Users/liuzexin/go/src/gotest/mtest.go:63 +0xec

Goroutine 6 (finished) created at:
  main.main()
      C:/Users/liuzexin/go/src/gotest/mtest.go:63 +0xec
==================
989
Found 1 data race(s)
exit status 66

解決方式

方式1:使用互斥鎖sync.Mutex
方式2:使用管道

使用管道的效率要比互斥鎖高,也符合Go語言的設計思想.