Ordem de saída do canal Golang
func main() {
messages := make(chan string)
go func() { messages <- "hello" }()
go func() { messages <- "ping" }()
msg := <-messages
msg2 := <-messages
fmt.Println(msg)
fmt.Println(msg2)
O código acima sempre imprime "ping" e depois "olá" no meu terminal. Estou confuso sobre a ordem em que isso é impresso, então fiquei pensando se poderia obter algum esclarecimento sobre meu pensamento.
Entendo que os canais sem buffer estão bloqueando enquanto aguardam um remetente e um destinatário. Portanto, no caso acima, quando essas rotinas 2 go são executadas, ainda não existe, em ambos os casos, um receptor. Então, estou supondo que as duas rotinas bloqueiem até que um receptor esteja disponível no canal.
Agora ... eu assumiria que o primeiro "olá" é tentado no canal, mas tem que esperar ... ao mesmo tempo, "ping" tenta, mas novamente tem que esperar. Então
msg := <- messages
aparece, então eu assumiria que, nessa fase, o programa escolherá arbitrariamente uma das goroutines em espera e permitirá que ele envie sua mensagem para o canal, já que a msg está pronta para receber.
No entanto, parece que não importa quantas vezes eu execute o programa, sempre é a msg que recebe "ping" e a msg2 é atribuída "hello", o que dá a impressão de que "ping" sempre tem prioridade para enviar primeiro (para msg). Por que é que?