在并发的使用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架构师原理