英文:
Why does this example put all goroutines to sleep?
问题
// 蛋糕有一个私有的通道,用来告诉我们何时烤好了。
type Cake struct {
BakingStatus chan string
}
// 烤箱立即通知每个蛋糕它已经烤好了。
func Oven(cakes chan *Cake) {
for c := range cakes {
c.BakingStatus <- "Done"
}
}
func main() {
cakes := make(chan *Cake)
go Oven(cakes)
myCake := &Cake{}
cakes <- myCake // 把蛋糕放进烤箱。
<-myCake.BakingStatus // 等待蛋糕烤好。
fmt.Println(myCake)
}
(这个例子很愚蠢和牵强,因为我为了这篇文章的目的将其简化到了绝对的最小程度。)
在我的脑海中,这个程序应该按照以下步骤工作:
Oven
协程休眠,直到有东西被发送到cakes
通道。myCake
被发送到cakes
通道。Oven
协程接收到蛋糕。- 主协程休眠,直到有东西被发送到
myCake.BakingStatus
通道。 Oven
向myCake.BakingStatus
通道发送一个值,并继续休眠。- 主协程接收到
myCake
并打印它。
我能想象的唯一的问题是,在主协程发送蛋糕和 Oven
协程接收蛋糕之间有一个瞬间,它们都处于休眠状态。但是解决方案是什么呢?
英文:
// Cakes have a private channel to let us know when they're done.
type Cake struct {
BakingStatus chan string
}
// Oven instantly notifies every cake that it is done.
func Oven(cakes chan *Cake) {
for c := range cakes {
c.BakingStatus <- "Done"
}
}
func main() {
cakes := make(chan *Cake)
go Oven(cakes)
myCake := &Cake{}
cakes <- myCake // Put the cake in the oven.
<-myCake.BakingStatus // Wait for cake to be done.
fmt.Println(myCake)
}
(This example is silly and contrived because I've pared it down to the absolute minimum for the sake of this post.)
In my head, this should work by the following steps:
- The Oven goroutine sleeps until something is sent on
cakes
. myCake
is sent tocakes
.- The Oven goroutine receives the cake.
- The main goroutine sleeps until something is sent on
myCake.BakingStatus
. Oven
sends a value tomyCake.BakingStatus
and goes back to sleep.- The main goroutine receives
myCake
and prints it.
The only problem I can imagine is that there's a moment between the main goroutine sending and the Oven goroutine receiving the cake where they're both asleep. But then what is the solution?
答案1
得分: 4
"BakingStatus"未初始化。写入和读取空通道会永远阻塞。
myCake := &Cake{
BakingStatus: make(chan string),
}
英文:
The "BakingStatus" is not initialized. Writing to and reading from a nil channel blocks forever.
myCake := &Cake{
BakingStatus: make(chan string),
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论