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了。

怎么避免这个问题,有两种方式。

第一种,将“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架构师

转载于:https://my.oschina.net/u/222608/blog/842463

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值