file
Golang
goroutine是Go語言強大的特性之一,合理的利用它才能發揮最大的價值
1、經調查
發現初學者一般會犯以下錯誤使用goroutine
func goroutineRun(values []int) {
for value := range values {
go value.test()
}
}
或者使用閉包調用
func goroutineRun(values []int) {
for value := range values {
go func() {
fmt.Println(value)
}()
}
}
這2段代碼實際上是遍歷數組的所有變量。由于閉包只是綁定到這個value變量上,并沒有被保存到goroutine棧中,所以以上代碼極有可能運行的結構都輸出為切片的最后一個元素。因為這樣寫會導致for循環結束后才執行goroutine多線程操作,這時候value值只指向了最后一個元素。這樣的結果不是我們所希望的,而且還會產生并發的資源搶占沖突所以是非常不推薦這樣寫的。
2、解決方法
goroutine的正確寫法
for val := range values {
go func(val interface{}) {
fmt.Println(val)
}(val)
}
在這里將 val 作為一個參數傳入 goroutine 中,每個 val 都會被獨立計算并保存到 goroutine 的棧中,從而得到預期的結果。
另一種方法是在循環內定義新的變量,由于在循環內定義的變量在循環遍歷的過程中是不共享的,因此也可以達到同樣的效果:
for i := range valslice {
val := valslice[i]
go func() {
fmt.Println(val)
}()
}