Maison >développement back-end >Golang >Pourquoi l'ordre de sortie des canaux sans tampon de Golang semble-t-il contre-intuitif ?

Pourquoi l'ordre de sortie des canaux sans tampon de Golang semble-t-il contre-intuitif ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-16 21:15:12323parcourir

Why Does Golang's Unbuffered Channel Output Order Seem Counterintuitive?

Comprendre l'ordre de sortie des canaux dans Golang

Dans Golang, les canaux non tamponnés fournissent un mécanisme de communication fiable entre les goroutines. Cependant, leur ordre de sortie peut parfois prêter à confusion. Considérez le code suivant :

func main() {
  messages := make(chan string)
  go func() { messages <- "hello" }()
  go func() { messages <- "ping" }()
  msg := <-messages
  msg2 := <-messages
  fmt.Println(msg)
  fmt.Println(msg2)
}

Lors de l'exécution de ce code, il affiche systématiquement « ping » suivi de « bonjour ». Cela peut sembler contre-intuitif, car on pourrait s'attendre à ce que le résultat corresponde à l'ordre dans lequel les goroutines ont été créées.

Pour comprendre pourquoi cela se produit, il est essentiel de se rappeler que les canaux sont des pipelines de communication, tandis que les goroutines représentent des tâches parallèles. L'ordre d'exécution des goroutines n'est pas garanti, même si elles ont été créées dans un ordre précis.

Dans ce cas, le planificateur peut avoir programmé la goroutine qui envoie "ping" avant celle qui envoie "bonjour". Lorsque le premier récepteur (c'est-à-dire msg := <-messages) devient disponible, il acceptera le message de la goroutine "ping" déjà programmée.

Dès réception du premier message, le programme continuera à s'exécuter jusqu'à ce que le deuxième récepteur (msg2 := <-messages) soit disponible. À ce stade, le message « bonjour » est prêt à être envoyé et il sera accepté comme deuxième message.

Par conséquent, l'ordre de sortie est déterminé par l'ordre d'exécution des goroutines qui écrivent sur le canal , et non l'ordre dans lequel ils sont créés ou l'ordre dans lequel les messages sont lus sur le canal. Pour vérifier cela, on peut ajouter une instruction Println aux goroutines, comme suggéré dans la réponse fournie :

...
func() { messages <- "hello"; fmt.Println("Hello sent") }()
func() { messages <- "ping"; fmt.Println("Ping sent") }()
...

Cela affichera :

Hello sent
Ping sent
ping
hello

Cela confirme que les messages ont été envoyés et imprimé dans le même ordre.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn