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

    公众号

  • 相关阅读:
    Python的数据类型--数字--字符串
    python基本--数据类型
    系统分区 ,硬盘格式化,
    linux 用户创建,权限,分组
    协程
    进程
    线程与进程--线程三把锁
    线程
    socket网络编程-字典
    socket网络编程
  • 原文地址:https://www.cnblogs.com/luolianxi/p/12741729.html
Copyright © 2011-2022 走看看