Golang 高并发编程For循环中使用Goroutine最容易犯的错误

file

Golang

goroutine是Go语言强大的特性之一,合理的利用它才能发挥最大的价值

1、经调查

发现初学者一般会犯以下错误使用goroutine

func goroutineRun(values []int)  {
    for value := range values {
        go value.test()
    }
}

或者使用闭包调用

func goroutineRun(values []int)  {
    for value := range values {
        go func() {
            fmt.Println(value)
        }()
    }
}

这2段代码实际上是遍历数组的所有变量。由于闭包只是绑定到这个value变量上,并没有被保存到goroutine栈中,所以以上代码极有可能运行的结构都输出为切片的最后一个元素。因为这样写会导致for循环结束后才执行goroutine多线程操作,这时候value值只指向了最后一个元素。这样的结果不是我们所希望的,而且还会产生并发的资源抢占冲突所以是非常不推荐这样写的。

2、解决方法

goroutine的正确写法

for val := range values {
    go func(val interface{}) {
        fmt.Println(val)
    }(val)
}

在这里将 val 作为一个参数传入 goroutine 中,每个 val 都会被独立计算并保存到 goroutine 的栈中,从而得到预期的结果。

另一种方法是在循环内定义新的变量,由于在循环内定义的变量在循环遍历的过程中是不共享的,因此也可以达到同样的效果:

for i := range valslice {
    val := valslice[i]
    go func() {
        fmt.Println(val)
    }()
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 常见的并发模式 Go语言最吸引人的地方是它内建的并发支持。Go语言并发体系的理论是C.A.R Hoare在1978...
    Gundy_阅读 3,485评论 0 7
  • 声明 这是一套帮助初学者从0到1学习go语言的开源教程,致力于打造最完整、最强悍、最有深度的Go语言学习体系 我希...
    唯识相链2阅读 1,090评论 0 2
  • 面向并发的内存模型 在早期,CPU都是以单核的形式顺序执行机器指令。Go语言的祖先C语言正是这种顺序编程语言的代表...
    Gundy_阅读 608评论 0 3
  • 人说: 林深时见鹿 海蓝时见鲸 梦醒时见你 可实际: 林深时雾气 ...
    Smile阿笑阅读 195评论 0 2
  • 只想九月九日 晚上 昌吉 寝室 “我刚借了4000块钱!太好了!我十一终于可以去成都了!” “你到那干啥去?” “...
    文吖青阅读 334评论 0 1