Maison > développement back-end > Golang > Pourquoi l'ordre de sortie des canaux non tamponnés de Go est-il non déterministe ?

Pourquoi l'ordre de sortie des canaux non tamponnés de Go est-il non déterministe ?

DDD
Libérer: 2024-12-07 11:03:12
original
277 Les gens l'ont consulté

Why is the output order of Go's unbuffered channels non-deterministic?

Ordre de sortie des chaînes Golang : une analyse plus approfondie

Comprendre l'ordre dans lequel les messages sont reçus d'une chaîne peut être un peu délicat dans Go . Examinons le code que vous avez fourni :

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

L'explication suivante répond à vos préoccupations et permet de mieux comprendre ce qui se passe :

Tout d'abord, il est important de comprendre que les opérations de blocage, telles que l'envoi ou la réception à partir de canaux non tamponnés ne garantissent pas une commande. Dans Go, l'exécution de la goroutine est simultanée et il n'y a pas d'ordre défini pour l'exécution de la goroutine par défaut.

Lorsque la première goroutine tente d'envoyer "bonjour" au canal, si aucun récepteur n'attend actuellement, la goroutine est bloqué. De même, lorsque la deuxième goroutine tente d'envoyer "ping", elle est également bloquée.

Maintenant, lorsque l'instruction msg := <-messages est atteinte, le programme débloquera arbitrairement l'une des goroutines bloquées. Le message envoyé par cette goroutine débloquée sera reçu dans msg.

Le même processus se produit pour msg2 := <-messages. Une autre goroutine sera débloquée et le message envoyé par cette goroutine sera reçu dans msg2.

L'ordre dans lequel les goroutines sont débloquées et transmettent leurs messages en messages n'est pas déterministe. C'est pourquoi vous voyez systématiquement « ping » imprimé avant « bonjour », même si vous supposiez que les routines auraient dû être exécutées alternativement.

Pour confirmer cela, vous pouvez essayer d'ajouter des instructions d'impression aux goroutines :

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

En exécutant le code plusieurs fois, vous remarquerez que l'ordre d'impression des instructions des goroutines peut varier. Cela démontre en outre la nature non déterministe de l'exécution des goroutines.

Pour résumer, l'ordre de sortie d'un canal n'est pas garanti dans les canaux non tamponnés, et cela dépend de l'ordre dans lequel les goroutines correspondantes sont débloquées.

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