在并发的使用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了。
怎么避免这个问题,有两种方式。
第一种,将“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()
}
第二种,传参数
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()
}
好了,就这么简单。
留一个小问题,为什么第一段代码输出的是5而不是4呢?
更多架构、PHP、GO相关踩坑实践技巧请关注我的公众号:PHP架构师