Maison > développement back-end > Golang > le corps du texte

Pourquoi le programme Go imprime-t-il la somme du calcul avant le message dans l'extrait de code donné, même si la goroutine principale se bloque jusqu'à ce qu'un signal soit reçu du canal ?

DDD
Libérer: 2024-10-29 21:49:29
original
493 Les gens l'ont consulté

Why does the Go program print the sum of the computation before the message in the given code snippet, even though the main goroutine blocks until a signal is received from the channel?

Concurrence Go et confusion des canaux

Dans Go, la concurrence permet à plusieurs tâches de s'exécuter simultanément à l'aide de goroutines. Les canaux facilitent la communication entre ces goroutines. Cependant, comprendre la simultanéité peut être difficile, en particulier lorsqu'il s'agit de canaux.

Considérez l'extrait de code suivant :

<code class="go">package main

import "fmt"

func display(msg string, c chan bool) {
    fmt.Println("display first message:", msg)
    c <- true
}

func sum(c chan bool) {
    sum := 0
    for i := 0; i < 10000000000; i++ {
        sum++
    }
    fmt.Println(sum)
    c <- true
}

func main() {
    c := make(chan bool)

    go display("hello", c)
    go sum(c)
    <-c
}</code>
Copier après la connexion

Dans ce code, nous créons deux goroutines : affichage et somme. La goroutine d'affichage imprime un message, envoie un signal au canal, puis attend une réponse. La goroutine somme effectue un long calcul, imprime le résultat et envoie également un signal au canal. Dans la goroutine principale, nous bloquons jusqu'à ce qu'un signal soit reçu du canal.

La sortie attendue du code est :

display first message: hello
Copier après la connexion

Cependant, nous observons que le programme imprime à la fois le message et la somme du calcul :

display first message: hello
10000000000
Copier après la connexion

Comprendre le problème

Le problème se pose en raison de la nature non déterministe de la planification des goroutines. Le planificateur de Go choisit librement entre les goroutines qui ne sont pas bloquées. Dans cet exemple, le planificateur peut exécuter n'importe laquelle des goroutines à tout moment.

Un ordre d'exécution possible est :

  1. main crée les goroutines.
  2. Le le planificateur sélectionne l'affichage, qui imprime le message et attend une réponse.
  3. Le planificateur passe à sum, qui s'exécute pendant une longue période.
  4. Le planificateur revient à l'affichage, qui envoie le signal .
  5. Le planificateur passe au principal, qui imprime le signal et quitte.

Dans ce scénario, la somme est imprimée avant que l'affichage n'envoie le signal, ce qui entraîne une sortie inattendue.

Solution

Pour garantir que le programme imprime uniquement le message et se termine avant que la somme ne soit calculée, nous pouvons utiliser une approche différente :

<code class="go">func main() {
    result := make(chan string)

    go display("hello", result)
    go sum(result)

    fmt.Println(<-result)
}</code>
Copier après la connexion

Dans cette version révisée, le canal résultat porte une seule valeur, le message de la goroutine d'affichage. La goroutine principale imprime désormais la valeur du canal, s'assurant qu'elle reçoit le message avant de quitter.

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!

source:php.cn
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
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!