輕鬆檢測Golang併發的資料競爭
Golang中我們使用Channel或者sync.Mutex等鎖保護資料,有沒有一種機制可以檢測程式碼中的資料競爭呢?
資料競爭是併發情況下,存在多執行緒/協程讀寫相同資料的情況,必須存在至少一方寫。另外,全是讀的情況下是不存在資料競爭的。
使用race檢測資料競爭
go build
有個標記race
可以幫助檢測程式碼中的資料競爭。
➜awesome git:(master) ✗ go help build //.... omit -race enable data race detection. Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
下面舉個栗子:
package main import "fmt" func main() { i := 0 go func() { i++ // write i }() fmt.Println(i) // read i }
測試方法:
➜awesome git:(master) ✗ go build -race hi.go ➜awesome git:(master) ✗ ./hi 0 ================== WARNING: DATA RACE Write at 0x00c00009c008 by goroutine 6: main.main.func1() /Users/mac/go/src/github.com/mac/awesome/hi.go:9 +0x4e Previous read at 0x00c00009c008 by main goroutine: main.main() /Users/mac/go/src/github.com/mac/awesome/hi.go:12 +0x88 Goroutine 6 (running) created at: main.main() /Users/mac/go/src/github.com/mac/awesome/hi.go:8 +0x7a ================== Found 1 data race(s) exit status 66
提示示例程式碼存在1處資料競爭,說明了資料會在第9行寫,並且同時會在12行讀形成了資料競爭。
當然你也可以使用go run
一步到位:
➜awesome git:(master) ✗ go run -race hi.go 0 ================== WARNING: DATA RACE Write at 0x00c000094008 by goroutine 6: main.main.func1() /Users/shitaibin/go/src/github.com/shitaibin/awesome/hi.go:9 +0x4e Previous read at 0x00c000094008 by main goroutine: main.main() /Users/shitaibin/go/src/github.com/shitaibin/awesome/hi.go:12 +0x88 Goroutine 6 (running) created at: main.main() /Users/shitaibin/go/src/github.com/shitaibin/awesome/hi.go:8 +0x7a ================== Found 1 data race(s) exit status 66
如果這篇文章對你有幫助,請點個贊/喜歡,讓我知道我的寫作是有價值的,感謝。