golang中函数闭包遇到的坑
2016-03-09 14:43
387 查看
golang项目中用到kafka,有个组件需要拉取消息;这个组件启动是成功的,有的时候能拉取消息;有的时候感觉像卡死了一样,有消息了,一条都没有拉取到。kafka测试没问题;最后定位到,原来是函数闭包用的有问题。
看下面这段代码,看起来似乎是两个goroutine,我们把rId作为goroutine的标记,结果想象应该是:
而实际测试的结果是:
s变量在循环的过程中已经被修改了,因此结果变成了这样。我们的项目中去获取kafka partition然后每个partition创建一个goroutine去消费的时候,就这样只会消费最后一个partition的数据,因此出现问题。
可以和rId一样过将变量作为匿名函数的参数传入进去,如下:
看下面这段代码,看起来似乎是两个goroutine,我们把rId作为goroutine的标记,结果想象应该是:
1 abcdef 0 123456 0 123456 1 abcdef 1 abcdef ......
package main import ( "fmt" "sync" "time" ) func main(){ strSlice := make([]*string, 0) s1 := "123456" strSlice = append(strSlice, &s1) s2 := "abcdef" strSlice = append(strSlice, &s2) var wg sync.WaitGroup for i,s := range strSlice{ wg.Add(1) go func(rId int){ for{ fmt.Println(rId, *s) time.Sleep(1 * time.Second) } wg.Done() }(i) } wg.Wait() }
而实际测试的结果是:
1 abcdef 0 abcdef 0 abcdef 1 abcdef 1 abcdef 0 abcdef 0 abcdef 1 abcdef 1 abcdef 0 abcdef 0 abcdef ......
s变量在循环的过程中已经被修改了,因此结果变成了这样。我们的项目中去获取kafka partition然后每个partition创建一个goroutine去消费的时候,就这样只会消费最后一个partition的数据,因此出现问题。
可以和rId一样过将变量作为匿名函数的参数传入进去,如下:
for i,s := range strSlice{ wg.Add(1) go func(rId int, rS *string){ for{ fmt.Println(rId, *rS) time.Sleep(1 * time.Second) } wg.Done() }(i, s) }
相关文章推荐
- Android之使用Http协议实现文件上传功能
- 深入理解PHP之匿名函数
- 最后一次说说闭包
- Go 语言 Channel 实现原理精要
- mysql集群之MMM简单搭建
- Go语言将支持Android
- Mootools 1.2教程 函数
- autoit InputBox 函数
- 通晓网络测试常用命令
- 文件遍历排序函数
- Ruby中使用Block、Proc、lambda实现闭包
- Oracle 函数大全[字符串函数,数学函数,日期函数]第1/4页
- ASP下经常用的字符串等函数参考资料
- PostgreSQL教程(五):函数和操作符详解(1)
- DOS批处理 函数定义与用法
- asp Chr 函数 数字转字母的方法
- Lua中的函数精讲笔记
- Lua中的闭合函数、非全局函数与函数的尾调用详解
- Lua中调用C++函数示例
- LUA中的闭包(closure)浅析