在併發的使用golang閉包的時候有一個共享變量問題要注意一下,看一段代碼golang
package main import ( "fmt" "sync" ) func main() { var ( wg sync.WaitGroup ) for i := 0; i < 5; i++ { wg.Add(1) go func() { fmt.Println(i) wg.Done() }() } wg.Wait() }
輸出結果閉包
5 5 5 5 5
???什麼狀況,爲何不是0 ~ 4 的亂序組合?架構
由於主協程和子協程是有執行順序的,也就是使用主協程在一個時間片(不太明白的話,能夠看看CPU調度的相關資料,原理相似)內徹底是本身的show time,當它時間片用完以後,才輪到子協程執行,而這個時候,變量「i」已是5了。併發
怎麼避免這個問題,有兩種方式。code
第一種,將「i」付給一個臨時變量。協程
package main import ( "fmt" "sync" ) func main() { var ( wg sync.WaitGroup ) for i := 0; i < 5; i++ { t:=i wg.Add(1) go func() { fmt.Println(t) wg.Done() }() } wg.Wait() }
第二種,傳參數it
package main import ( "fmt" "sync" ) func main() { var ( wg sync.WaitGroup ) for i := 0; i < 5; i++ { wg.Add(1) go func(t int) { fmt.Println(t) wg.Done() }(i) } wg.Wait() }
好了,就這麼簡單。import
留一個小問題,爲何第一段代碼輸出的是5而不是4呢?變量
更多架構、PHP、GO相關踩坑實踐技巧請關注個人公衆號:PHP架構師原理