zoukankan      html  css  js  c++  java
  • 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)
        }()
    }
    

    公众号

  • 相关阅读:
    C#计算代码的执行耗时
    c#值类型和引用类型
    C#类、接口、虚方法和抽象方法
    15,了解如何在闭包里使用外围作用域中的变量
    函数闭包,golbal,nonlocal
    init())函数和main()函数
    函数的命名空间
    函数的默认参数是可变不可变引起的奇怪返回值
    遍历目录
    super顺序
  • 原文地址:https://www.cnblogs.com/luolianxi/p/12741729.html
Copyright © 2011-2022 走看看