func main() {
messages := make(chan string)
go func() { messages <- "hello" }()
go func() { messages <- "ping" }()
msg := <-messages
msg2 := <-messages
fmt.Println(msg)
fmt.Println(msg2)
Run Code Online (Sandbox Code Playgroud)
上面的代码在我的终端上始终打印"ping"然后"hello".我对这个打印的顺序很困惑,所以我想知道我是否可以对我的想法做一些澄清.
据我所知,在等待发送方和接收方时,无缓冲的通道都在阻塞.因此,在上述情况下,当执行这两个例程时,在两种情况下都没有接收器.所以我猜这两个例程都会阻塞,直到通道上的接收器可用.
现在......我会假设第一个"你好"被尝试进入频道,但必须等待......同时,"ping"尝试,但再次必须等待.然后
msg := <- messages
Run Code Online (Sandbox Code Playgroud)
显示,所以我假设在那个阶段,程序将任意选择一个等待的goroutine并允许它将其消息发送到通道,因为msg已准备好接收.
然而,似乎无论我运行多少次程序,总是msg被分配"ping"而msg2被分配为"hello",这给人的印象是"ping"始终优先发送到第一个(到MSG).这是为什么?
在 Golang Spec Channels order中描述为:-
通道充当先进先出队列。例如,如果一个 goroutine 在通道上发送值,而第二个 goroutine 接收它们,则按照发送的顺序接收值。
它将打印哪个值首先可用以在另一端接收。如果要同步它们,请使用不同的频道或添加wait Groups
.
package main
import (
"fmt"
)
func main() {
messages1 := make(chan string)
messages2 := make(chan string)
go func(<-chan string) {
messages2 <- "ping"
}(messages2)
go func(<-chan string) {
messages1 <- "hello"
}(messages1)
fmt.Println(<-messages1)
fmt.Println(<-messages2)
}
Run Code Online (Sandbox Code Playgroud)
如果您看到,您可以根据您的选择使用不同的渠道轻松获得您想要的任何价值。