我敢肯定对这种琐碎的情况有一个简单的解释,但是我对go并发模型是陌生的。
go
当我运行这个例子
package main import "fmt" func main() { c := make(chan int) c <- 1 fmt.Println(<-c) }
我收到此错误:
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan send]: main.main() /home/tarrsalah/src/go/src/github.com/tarrsalah/tour.golang.org/65.go:8 +0x52 exit status 2
为什么呢
包装c <-成一个goroutine使示例按预期运行
c <-
goroutine
package main import "fmt" func main() { c := make(chan int) go func(){ c <- 1 }() fmt.Println(<-c) }
再次,为什么?
请,我需要深入的解释,而不仅仅是如何消除死锁并修复代码。
从文档中:
如果通道未缓冲,则发送方将阻塞,直到接收方收到该值为止。如果通道具有缓冲区,则发送方仅阻塞该值,直到将值复制到该缓冲区为止;否则,发送方才阻塞。如果缓冲区已满,则意味着要等到某些接收器检索到一个值。
否则说:
这条线
c <- 1
阻塞,因为通道没有缓冲。由于没有其他goroutine可以接收该值,因此情况无法解决,这是一个僵局。
您可以将频道创建更改为
c := make(chan int, 1)
这样,频道在被阻止之前就可以容纳一个项目。
但这不是并发的意义所在。通常,没有其他goroutine不会使用通道来处理放入内部的内容。您可以这样定义一个接收goroutine:
func main() { c := make(chan int) go func() { fmt.Println("received:", <-c) }() c <- 1 }
示范