go - 作为 goroutines 启动的 3 个不同的函数产生相同的 goroutine(显然忽略参数)

标签 go concurrency goroutine

对于 3 个不同且不同的“c”

for _, c := range u.components { // u.components has 3 members
    fmt.Printf("%v %v", c.name, c.channel) // prints 3 distinct name/channel pairs 
    go c.Listen(); // a method of c that listens on channel c.channel
}

...启动 3 个相同的 goroutine,其中 c.name 和 c.channel 相同。

长版本(注释,短代码): https://play.golang.org/p/mMQb_5jLjm

这是我的第一个 Go 程序,我确信我遗漏了一些明显的东西。有什么想法吗?

谢谢。

最佳答案

c.Listen() 的调用关闭了 c 的值,它通过指向 Listen 的指针传递,并且每次迭代都会更改该值。如果将方法调用视为方法表达式,则更容易可视化

go (*component).Listen(&c)

https://golang.org/doc/faq#closures_and_goroutines

在每次迭代时为 c 创建一个新值,以防止先前的值被覆盖:

for _, c := range u.components { // u.components has 3 members
    c := c
    fmt.Printf("%v %v", c.name, c.channel) // prints 3 distinct name/channel pairs 
    go c.Listen(); // a method of c that listens on channel c.channel
}

或者直接使用 slice 中包含的值:

for i := range u.components {
    go u.components[i].Listen()
}

关于go - 作为 goroutines 启动的 3 个不同的函数产生相同的 goroutine(显然忽略参数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34495465/

相关文章:

go - Go 中的 Python 样式生成器

go - http中的Goroutines

pointers - Go循环指针变化

go - Go如何安全存储?

java - volatile 变量的更新值对其他线程不可见

java - 这是没有被破坏的双重检查锁定吗?

Go,将数据传递到 channel

file - 戈兰 : Getting "fatal error: all goroutines are asleep - deadlock" on waitGroup. 等待()

go - 您可以通过 json 键字段动态迭代 Go 中的结构字段吗?

java - 线程安全地在两个数组列表之间移动数组列表元素