zoukankan      html  css  js  c++  java
  • Golang循环中调用go func参数异常分析

    项目中,需要循环调用API服务器列表,在循环中使用go func创建协程时遇到了参数失灵的现象.
    具体代码如下所示:

    	for _, apiServerAddr := range apiServerAddrList {
    		go func() {
    			callApiServer(apiServerAddr)
    		}()
    	}
    

    在运行过程中,发现callApiServer中参数apiServerAddr实际值一直是apiServerAddrList 的最后一个元素值.
    将代码修改为如下形式,则每一个创建的协程中apiServerAddr 则是循环的数值.

    	for _, apiServerAddr := range apiServerAddrList {
    		go callApiServer(apiServerAddr)
    	}
    

    查询stackoverflow,发现原因如下:

    • 循环中,go callApiServer(apiServerAddr)创建的协程中,使用的apiServerAddr是其数值;
    • 循环中,go func(){callApiServer(apiServerAddr)}()创建的协程中,使用的apiServerAddr是其引用,在循环执行至一定次数后,Golang调度器调度协程,协程获取当前时刻apiServerAddr的数值,此时就会产生错误.

    golang的闭包,能够从创建它的作用域中获取变量,且获取的是变量的引用而非变量的副本.

    go func修改为如下格式,能够正确调用:

    	for _, apiServerAddr := range apiServerAddrList {
    		go func(addr string) {
    			callApiServer(addr )
    		}(apiServerAddr )
    	}
    

    PS:
    如果您觉得我的文章对您有帮助,请关注我的微信公众号,谢谢!
    程序员打怪之路

  • 相关阅读:
    as3 绕中心点旋转
    TweenMax
    As3支持的Html标签一览
    AS3.0 静音和停止所有声音
    as3 如何判断同时按下两个键
    前置窗体
    系统音效控制
    LocalConnection
    as3代码实现调用摄像头
    air 加载网页
  • 原文地址:https://www.cnblogs.com/jason1990/p/10796236.html
Copyright © 2011-2022 走看看