博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang协程注意全局变量和局部变量
阅读量:3989 次
发布时间:2019-05-24

本文共 1218 字,大约阅读时间需要 4 分钟。

我们会经常性的使用如下片段

for k, v := range sli {
go ...}

来看下面的例子

func main() {
sli := []int{
1, 2, 3, 4, 5, 6, 7, 8, 9} wg := sync.WaitGroup{
} for k, v := range sli {
wg.Add(1) go func() {
time.Sleep(time.Second) fmt.Println(k, v) wg.Done() }() } wg.Wait()}

打印输出

8 98 98 98 98 98 98 98 98 9

结果和想象的不一样,主要原因出在协程这里,如果不使用协程,而是使用串行的方式,结果结合预期一致,比如

func main() {
sli := []int{
1, 2, 3, 4, 5, 6, 7, 8, 9} for k, v := range sli {
func() {
time.Sleep(time.Second) fmt.Println(k, v) }() }}

打印输出

0 11 22 33 44 55 66 77 88 9

其中 k, v 是迭代变量,每次迭代都会给 k, v 赋值新的值,并且多个协程又同时调用了 k, v ,所以结果就串了,解决方式就是定义一个局部变量。

func main() {
sli := []int{
1, 2, 3, 4, 5, 6, 7, 8, 9} wg := sync.WaitGroup{
} for k, v := range sli {
wg.Add(1) k1 := k v1 := v go func() {
time.Sleep(time.Second) fmt.Println(k1, v1) wg.Done() }() } wg.Wait()}

打印输出

4 51 22 38 97 85 66 70 13 4

k1, v1 是局部变量,每次循环,循环体内是不共享的,这也是为什么可以这样声明变量(k1 := k)。

或者通过传参的方式来固定下来

func main() {
sli := []int{
1, 2, 3, 4, 5, 6, 7, 8, 9} wg := sync.WaitGroup{
} for k, v := range sli {
wg.Add(1) go func(k, v interface{
}) {
time.Sleep(time.Second) fmt.Println(k, v) wg.Done() }(k, v) } wg.Wait()}

转载地址:http://kjaui.baihongyu.com/

你可能感兴趣的文章
输入设备节点自动生成
查看>>
dynamic generate command line parameters for qt embedded application
查看>>
opencv test code-1
查看>>
烟台地铁路线图 Yantai Subway
查看>>
eclipse 导入先前存在的项目
查看>>
GNU hello代码分析
查看>>
Qt继电器控制板代码
查看>>
imx6 项目的按键驱动程序
查看>>
busybox passwd修改密码
查看>>
wpa_supplicant控制脚本
查看>>
rfkill: WLAN hard blocked
查看>>
gstreamer相关工具集合
查看>>
gstreamer 捕获图像+存储示例代码
查看>>
arm 自动升级脚本
查看>>
RS232 四入四出模块控制代码
查看>>
gstreamer插件之 videotestsrc
查看>>
gstreamer插件之 v4l2src
查看>>
autoupdate script
查看>>
EAVCapture项目中的开机自动升级脚本
查看>>
在linux2.6内核中加入自己的驱动
查看>>