作者:血狼2732_150 | 来源:互联网 | 2023-02-01 15:56
例如:
type name struct {
name string
age int
}
func main() {
c := make(chan name)
c <- name{"sfsaf", 1}
a, b := <- c
close(c)
}
结果:
致命错误:所有goroutines都睡着了 - 僵局!
我想通过渠道传递价值.我该怎么办?
1> eduncan911..:
是的,你可以通过结构.但这不是你的OP中的问题.
当没有接收器准备接收时,您在通道上发送了一个值.这就是造成你僵局的原因.
频道希望receiver
阻止,等待sender
.这是通过Goroutines完成的.
因此,请将您的发件人包装在goroutine中,该goroutine不会立即执行.
package main
import (
"fmt"
)
type name struct {
name string
age int
}
func main() {
c := make(chan name)
go func() {
c <- name{"sfsaf", 1}
close(c)
}()
for n := range c {
fmt.Println(n)
}
fmt.Println("channel was closed (all done!).")
}
在操场上看到它:https://play.golang.org/p/uaSuCaB4Ms
这是因为发件人的goroutine尚未执行.直到当前的goroutine执行被阻止.
我们在for n := range c
循环中受阻.这是接收器,坐着等待价值观.(这是一种常见的模式,使用for循环迭代通道值,因为它将坐下并阻塞,等待值).
所以现在我们被阻止等待接收for
循环中的值,内联gorouting现在将执行,以在通道上发送我们的值.
此外,我们遵循安全实践并在我们自己和close(c)
渠道之后整理,发出for
循环或select
声明,表示不再发送任何值. 发件人总是关闭,而不是收件人.这是for
范围循环用于退出for循环的模式,并继续执行其余代码.
作为旁注,你通过传递结构的值 - 而不是指针 - 做得很好.
如果你传递了一个指针,你必须在对象周围实现一些互斥锁,以防止R/W恐慌.
不要通过共享内存进行通信; 相反,通过沟通分享记忆.
坚持传递价值,而不是指针,围绕你的渠道和goroutines,并获得好处.