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:
如果您觉得我的文章对您有帮助,请关注我的微信公众号,谢谢!
Golang循环中调用go func参数异常分析的更多相关文章
- javascript 循环中调用异步的同步需求
// 关于Promise:可以直接使用promise Promise.resolve(123).then(v => { console.log(v) }) // 循环中调用异步 let arr ...
- golang 反射中调用方法
反射中调用函数 众所周知,golang中的函数是可以像普通的int.float等类型变量那样作为值的,例如: package main import "fmt" func hell ...
- shell下在while循环中使用ssh命令的问题
1 现象描述 最近使用ssh批量执行命令(已经做了密钥互信了),脚本读取配置文件中的主机列表(内容为每行一台主机IP地址),然后执行,可是每次只是执行第一台,就退出循环了. 2 排查思路 由于脚本比较 ...
- spring中for循环中事务
1.需求:批量插入一批数据,不用spring jdbc的批处理,用for循环插入数据. 2.遇到的问题:在for循环中,当一个插入不成功,前面插入成功的数据也将回滚. 3.初始设计:在service中 ...
- 关于由ajax返回的数据在for循环中只能取到最后一个数的问题
关于由ajax返回的数据在for循环中只能取到最后一个数的问题 以上是来自后台的数据格式.从数据中可以看出,里面包含两个商品,每个商品价格分别为:1.98,13.60.这里我要计算两个商品的总价格,但 ...
- 【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 ...
- 如何给ioloop.run_sync()中调用的函数传入参数
问题 如何给tornado.ioloop.IOLoop中的run_sync方法中调用的函数添加参数 解决方案 使用functools.partial 解决示例 from tornado import ...
- 使用“2”个参数调用“SetData”时发生异常:“程序集“
使用"2"个参数调用"SetData"时发生异常:"程序集"Microsoft.VisualStudio.ProjectSystem.VS. ...
- 【问题】Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数
[问题]Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数. [解决]直接对变量加引号,如: <button onclick="deleteProduct('@ ...
随机推荐
- MySQL数据库 介绍,安装,基本操作
- 数据库介绍: 1.随意存放在一个文件中的数据,数据的格式千差万别 tank|123 jason:123 sean~123 2.软件开发目录规范 - Project: - conf - bin - ...
- Gym101667 H. Rock Paper Scissors
将第二个字符串改成能赢对方时对方的字符并倒序后,字符串匹配就是卷积的过程. 那么就枚举字符做三次卷积即可. #include <bits/stdc++.h> struct Complex ...
- <Random> 380 381(hard) 138
380. Insert Delete GetRandom O(1) class RandomizedSet { ArrayList<Integer> nums; HashMap<In ...
- B1020 月饼(25分)
#include<cstdio> #include<algorithm> #include<iostream> using namespace std; struc ...
- echarts 中 柱图 、折线图、柱图层叠
app.title = '折柱混合'; option = { tooltip: { trigger: 'axis', axisPointer: { type: 'cross', crossStyle: ...
- [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 ...
- Eureka工作原理分析
demo源码地址:https://github.com/flyingJiang/SpringCloud 首先,单独使用Eureka. Eureka整合Ribbon 未完待续……
- RHEL8/CentOS8的基础防火墙配置-用例
systemctl systemctl unmask firewalld #执行命令,即可实现取消服务的锁定 systemctl mask firewalld # 下次需要锁定该服务时执行 syste ...
- windows远程复制中断无法复制
关掉对应的rdpclip进程,再创建一个
- 多线程避免使用SimpleDateFormat及替代方案
先来看一个多线程下使用例子,看到运行结果会出现异常: import java.text.DateFormat; import java.text.SimpleDateFormat; import ja ...
