Maison > développement back-end > Golang > Pourquoi l'ordre de sortie est-il imprévisible dans les canaux sans tampon de Golang ?

Pourquoi l'ordre de sortie est-il imprévisible dans les canaux sans tampon de Golang ?

Barbara Streisand
Libérer: 2024-12-07 06:37:16
original
309 Les gens l'ont consulté

Why is the Output Order Unpredictable in Golang's Unbuffered Channels?

Comprendre l'ordre de sortie des canaux Golang

Les canaux sans tampon dans Golang introduisent un aspect intéressant de la programmation simultanée où l'ordre de livraison des messages d'un expéditeur à un destinataire peut être imprévisible. Explorons pourquoi en utilisant un exemple de code spécifique et son analyse.

Extrait de code

func main() {
  messages := make(chan string)
  go func() { messages <- "hello" }()
  go func() { messages <- "ping" }()
  msg := <-messages
  msg2 := <-messages
  fmt.Println(msg)  // "ping"
  fmt.Println(msg2) // "hello"
}
Copier après la connexion

Flux d'exécution

Comme les deux goroutines de l'expéditeur s'exécutent simultanément, il n'y a aucune garantie concernant quel message est envoyé en premier dans le canal. Dans ce code spécifique, vous observez systématiquement que « ping » est imprimé en premier et « bonjour » en second. Cela est dû à la nature non déterministe de la planification des goroutines dans Golang.

Comprendre le non-déterminisme

Les goroutines dans Golang sont planifiées par le moteur d'exécution, ce qui signifie que leur ordre d'exécution n'est pas prévisible. Il s'agit d'un aspect crucial de la programmation simultanée où la disponibilité des cœurs, les algorithmes de planification des threads et la nature de votre code peuvent influencer l'ordre d'exécution.

Impression à partir des Sender Goroutines

Pour illustrer ce non -déterminisme plus loin, pensez à modifier le code pour imprimer les messages des goroutines de l'expéditeur :

func main() {
  messages := make(chan string)
  
  // Print before writing to the channel
  go func() { fmt.Println("Sending hello"); messages <- "hello" }()
  go func() { fmt.Println("Sending ping"); messages <- "ping" }()
  
  // Receive messages and print
  msg := <-messages
  msg2 := <-messages
  fmt.Println(msg)
  fmt.Println(msg2)
}
Copier après la connexion

Dans ce code modifié, vous pourriez observer l'ordre de sortie suivant :

Sending hello
Sending ping
ping
hello
Copier après la connexion

Cela démontre que la goroutine qui a envoyé "bonjour" était programmée pour être exécutée et écrite sur le canal avant la goroutine qui a envoyé "ping", même si "ping" a été reçu et imprimé en premier dans la routine principale.

Conclusion

Les canaux sans tampon dans Golang ne garantissent pas l'ordre de livraison des messages. L'ordre de réception des messages dépend de la nature non déterministe de la planification des goroutines au moment de l'exécution. Pour éviter toute confusion potentielle, il est essentiel de comprendre ce non-déterminisme et de prendre les mesures appropriées lorsque cela est nécessaire.

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 de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal