golang使用闭包时的共享变量问题

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

相关文章
相关标签/搜索