【发布时间】:2018-11-12 06:05:45
【问题描述】:
func main() {
messages := make(chan string)
go func() { messages <- "hello" }()
go func() { messages <- "ping" }()
msg := <-messages
msg2 := <-messages
fmt.Println(msg)
fmt.Println(msg2)
上面的代码在我的终端上始终打印“ping”,然后打印“hello”。 我对此打印的顺序感到困惑,所以我想知道是否可以澄清我的想法。
我了解无缓冲通道在等待发送方和接收方时会阻塞。因此,在上述情况下,当执行这两个 go 例程时,在这两种情况下都没有接收器。所以我猜这两个例程都会阻塞,直到通道上有接收器。
现在...我假设第一个“hello”尝试进入频道,但必须等待...同时,“ping”尝试,但又必须等待。那么
msg := <- messages
出现了,所以我假设在那个阶段,程序将任意选择一个等待的 goroutine 并允许它将消息发送到通道中,因为 msg 已准备好接收。
但是,似乎无论我运行多少次程序,总是被分配“ping”的 msg 和分配“hello”的 msg2,这给人的印象是“ping”总是优先发送首先(给味精)。这是为什么呢?
【问题讨论】:
-
你想要什么。你想同步频道以便
hello总是先打印吗? -
您的观察是正确的,线程的执行顺序(在 golang 的情况下,go 例程)并非设计为可预测的。如果您想以特定方式控制执行流程,也许这篇文章 (stackoverflow.com/questions/39818254/…) 可能会对您有所帮助。