为什么 golang 中的 select 只适用于 goroutine 中的通道?
Why does select in golang only works with channels in goroutine?
考虑以下 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
?
Shouldn't the code execute in a sequential manner in the first case so that by the time the select statement is reached, the msg will be passed and it will catch the case msg := <-messages ?
从未达到 select 语句,这是您第一个代码中的问题。
声明
messages <- "my msg"
想要将字符串推送到通道中,但由于您创建了一个无缓冲通道
messages := make(chan string)
goroutine 一直在等待有人真正从通道读取数据,因此它可以将字符串推送到通道。你可以只将一些东西推送到一个无缓冲的通道如果有一个goroutine从它读取的地方!
使用缓冲通道尝试第一个示例:
messages := make(chan string, 1)
它应该会如您所愿。
考虑以下 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
?
Shouldn't the code execute in a sequential manner in the first case so that by the time the select statement is reached, the msg will be passed and it will catch the case msg := <-messages ?
从未达到 select 语句,这是您第一个代码中的问题。
声明
messages <- "my msg"
想要将字符串推送到通道中,但由于您创建了一个无缓冲通道
messages := make(chan string)
goroutine 一直在等待有人真正从通道读取数据,因此它可以将字符串推送到通道。你可以只将一些东西推送到一个无缓冲的通道如果有一个goroutine从它读取的地方!
使用缓冲通道尝试第一个示例:
messages := make(chan string, 1)
它应该会如您所愿。