考虑以下go playground
package main
import "fmt"
func main() {
messages := make(chan string)
messages <- "my msg"
select {
case msg := <-messages:
fmt.Println("received message", msg)
}
}
上面的代码会出错
fatal error: all goroutines are asleep - deadlock!
然而
如果我将其更改为
package main
import "fmt"
func main() {
messages := make(chan string)
go func() {
messages <- "my msg"
}()
select {
case msg := <-messages:
fmt.Println("received message", msg)
}
}
它会起作用。
这种行为有特殊原因吗?
代码不应该在第一种情况下以顺序方式执行,以便在到达select语句时,msg将被传递并且它将捕获案例msg := <-messages
?
答案 0 :(得分:6)
代码不应该在第一种情况下以顺序方式执行,以便在达到select语句时,msg将被传递并且它将捕获case msg:=&lt; -messages?
永远不会达到select语句,这就是第一个代码中的问题。
声明
messages <- "my msg"
想要将字符串推入频道,但是因为您创建了一个无缓冲的频道
messages := make(chan string)
goroutine一直在等待某人实际从频道中读取,因此它可以将字符串推送到频道。您可以仅将某些内容推送到无缓冲的频道如果某处有一个goroutine读取内容!
尝试使用缓冲通道的第一个示例:
messages := make(chan string, 1)
它应该按照您的预期工作。