• 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)
        }()
    }
    

    公众号

  • 相关阅读:
    ....
    排序相关的问题(jq,java)_1123
    Spring aop 记录操作日志
    vue -element ui 自定义验证规则,封装在公共的文件里
    vue
    ES6 新特性
    正则表达式
    面向对象基础--继承(2)
    面向对象基础(1)
    安装vue环境
  • 原文地址:https://www.cnblogs.com/luolianxi/p/12741729.html
Copyright © 2020-2023  润新知