英文:
Getting error: all goroutines are asleep - deadlock
问题
为什么像这样简单的代码不起作用呢?
c1 := make(chan string)
c1 <- "foo"
fmt.Println(<-c1)
但是如果我将它放在一个go协程中,它就可以工作?
c1 := make(chan string)
go func() {
c1 <- "foo"
}()
fmt.Println(<-c1)
这个问题可能看起来很简单和愚蠢,但我试图理解为什么我不能这样做,而且我不知道还有什么更好的问题可以问。
英文:
How come something simple like this does not work?
c1 := make(chan string)
c1 <- "foo"
fmt.Println(<-c1)
But if I put it in a go routine it works?
c1 := make(chan string)
go func() {
c1 <- "foo"
}()
fmt.Println(<-c1)
The question might seem simple and stupid, but I'm trying to understand why I can't do this and I don't know of anything better to ask in this case.
答案1
得分: 7
通道c1是一个无缓冲通道。只有在发送方和接收方都准备好的情况下,无缓冲通道上的通信才会成功。
代码中的c1 <- "foo"
会永远阻塞,因为没有接收方准备好。
带有goroutine的程序可以正常工作,因为发送和接收的goroutine运行到发送方和接收方都准备好的点。
以下程序也可以正常工作:
c2 := make(chan string, 1) // <-- 注意通道大小为1
c2 <- "foo"
fmt.Println(<-c2)
这个程序中的通道c2是有缓冲的。发送操作c2 <- "foo"
可以继续进行,因为缓冲区不满。
英文:
Channel c1 is an unbuffered channel. Communication succeeds on an unbuffered channel only when both a sender and receiver are ready.
The line c1 <- "foo
blocks forever because no receiver is ready.
The program with the goroutine works because the sending and receiving goroutines run to the point where the sender and receiver are both ready.
This program will also work:
c2 := make(chan string, 1) // <-- note channel size of one
c2 <- "foo"
fmt.Println(<-c2)
Channel c2 is buffered in this program. The send c2 <- "foo"
proceeds because the buffer is not full.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论