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#成员设计建议
    基于任务的异步编程模式(TAP)的错误处理
    基于任务的异步编程模式(TAP)
    C#克隆
    C#操作excel打印
    父元素如何围住浮动子元素
    intellij idea创建第一个动态web项目
    Idea快捷键
    Python中列表的copy方法
    C++读取数量不定的数据
  • 原文地址:https://www.cnblogs.com/luolianxi/p/12741729.html
Copyright © 2011-2022 走看看