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

file

Golang

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

一、经调查

发现初学者通常会犯如下错误使用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值只指向了最后一个元素。这样的结果不是咱们所但愿的,并且还会产生并发的资源抢占冲突因此是很是不推荐这样写的。并发

二、解决方法

goroutine的正确写法线程

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

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

另外一种方法是在循环内定义新的变量,因为在循环内定义的变量在循环遍历的过程当中是不共享的,所以也能够达到一样的效果:blog

for i := range valslice {
    val := valslice[i]
    go func() {
        fmt.Println(val)
    }()
}

公众号

相关文章
相关标签/搜索