项目中,需要循环调用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:

如果您觉得我的文章对您有帮助,请关注我的微信公众号,谢谢!

Golang循环中调用go func参数异常分析的更多相关文章

  1. javascript 循环中调用异步的同步需求

    // 关于Promise:可以直接使用promise Promise.resolve(123).then(v => { console.log(v) }) // 循环中调用异步 let arr ...

  2. golang 反射中调用方法

    反射中调用函数 众所周知,golang中的函数是可以像普通的int.float等类型变量那样作为值的,例如: package main import "fmt" func hell ...

  3. shell下在while循环中使用ssh命令的问题

    1 现象描述 最近使用ssh批量执行命令(已经做了密钥互信了),脚本读取配置文件中的主机列表(内容为每行一台主机IP地址),然后执行,可是每次只是执行第一台,就退出循环了. 2 排查思路 由于脚本比较 ...

  4. spring中for循环中事务

    1.需求:批量插入一批数据,不用spring jdbc的批处理,用for循环插入数据. 2.遇到的问题:在for循环中,当一个插入不成功,前面插入成功的数据也将回滚. 3.初始设计:在service中 ...

  5. 关于由ajax返回的数据在for循环中只能取到最后一个数的问题

    关于由ajax返回的数据在for循环中只能取到最后一个数的问题 以上是来自后台的数据格式.从数据中可以看出,里面包含两个商品,每个商品价格分别为:1.98,13.60.这里我要计算两个商品的总价格,但 ...

  6. 【C#】无损转换Image为Icon 【C#】组件发布:MessageTip,轻快型消息提示窗 【C#】给无窗口的进程发送消息 【手记】WebBrowser响应页面中的blank开新窗口及window.close关闭本窗体 【手记】调用Process.EnterDebugMode引发异常:并非所有引用的特权或组都分配给呼叫方 【C#】DataRowState演变备忘

    [C#]无损转换Image为Icon 如题,市面上常见的方法是: var handle = bmp.GetHicon(); //得到图标句柄 return Icon.FromHandle(handle ...

  7. 如何给ioloop.run_sync()中调用的函数传入参数

    问题 如何给tornado.ioloop.IOLoop中的run_sync方法中调用的函数添加参数 解决方案 使用functools.partial 解决示例 from tornado import ...

  8. 使用“2”个参数调用“SetData”时发生异常:“程序集“

    使用"2"个参数调用"SetData"时发生异常:"程序集"Microsoft.VisualStudio.ProjectSystem.VS. ...

  9. 【问题】Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数

    [问题]Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数. [解决]直接对变量加引号,如: <button onclick="deleteProduct('@ ...

随机推荐

  1. MySQL数据库 介绍,安装,基本操作

    - 数据库介绍: 1.随意存放在一个文件中的数据,数据的格式千差万别 tank|123 jason:123 sean~123 2.软件开发目录规范 - Project: - conf - bin - ...

  2. Gym101667 H. Rock Paper Scissors

    将第二个字符串改成能赢对方时对方的字符并倒序后,字符串匹配就是卷积的过程. 那么就枚举字符做三次卷积即可. #include <bits/stdc++.h> struct Complex ...

  3. <Random> 380 381(hard) 138

    380. Insert Delete GetRandom O(1) class RandomizedSet { ArrayList<Integer> nums; HashMap<In ...

  4. B1020 月饼(25分)

    #include<cstdio> #include<algorithm> #include<iostream> using namespace std; struc ...

  5. echarts 中 柱图 、折线图、柱图层叠

    app.title = '折柱混合'; option = { tooltip: { trigger: 'axis', axisPointer: { type: 'cross', crossStyle: ...

  6. [LeetCode] 906. Super Palindromes 超级回文数

    Let's say a positive integer is a superpalindrome if it is a palindrome, and it is also the square o ...

  7. Eureka工作原理分析

    demo源码地址:https://github.com/flyingJiang/SpringCloud 首先,单独使用Eureka. Eureka整合Ribbon 未完待续……

  8. RHEL8/CentOS8的基础防火墙配置-用例

    systemctl systemctl unmask firewalld #执行命令,即可实现取消服务的锁定 systemctl mask firewalld # 下次需要锁定该服务时执行 syste ...

  9. windows远程复制中断无法复制

    关掉对应的rdpclip进程,再创建一个

  10. 多线程避免使用SimpleDateFormat及替代方案

    先来看一个多线程下使用例子,看到运行结果会出现异常: import java.text.DateFormat; import java.text.SimpleDateFormat; import ja ...