浅谈go 协程的使用陷阱

golang 语言协程

协程中使用全局变量、局部变量、指针、map、切片等作为参数时需要注意,此变量的值变化问题。 与for 循环,搭配使用更需谨慎。

1、内置函数时直接使用局部变量,未进行参数传递

func main() {

for i := 0; i < 100; i++ {

go func() {

fmt.Println(i)

}()

}

}

运行效果

func main() {

for i := 0; i < 100; i++ {

go func(i int) {

fmt.Println(i)

}(i)

}

}

运行效果

2、地址传递的参数

type Per struct {

name string

bh int

}

func main() {

p := &Per{}

for i := 0; i < 100; i++ {

p.bh = i

go func(p *Per) {

fmt.Println(p)

}(p)

}

}

分析: 导致以上非实际结果的原因是,go 之后并非立即启动协程的。

补充:Go for循环 协程间传递参数的一个问题

看代码吧~

map1 := make(map[int]int)

for i:=0; i<3; i++{

map1[i] = i+1

}

fmt.Println(map1)

for k, v := range map1{

go func(key, value int){

fmt.Println("one way :", key, " : ", value)

}(k, v)

go func(){

time.Sleep(time.Second)

fmt.Println("another way :", k, " : ", v)

}()

}

输出:

map[2:3 0:1 1:2]

one way : 1 : 2

one way : 0 : 1

one way : 2 : 3

another way : 2 : 3

another way : 2 : 3

another way : 2 : 3

这看起来跟 js 里面的 for 循环匿名函数传参的问题差不多。就是说匿名函数真正执行的时候,传入形参的值已经确定。

如果想要达到想要的效果需要进行第一种传参形式。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。

以上是 浅谈go 协程的使用陷阱 的全部内容, 来源链接: utcz.com/p/235736.html

回到顶部