Golang 高并发编程使用Goroutine容易犯的错误
阿俊 · · 1111 次点击 · · 开始浏览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)
}()
}
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
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)
}()
}