Heim  >  Artikel  >  Backend-Entwicklung  >  Warum gibt mein Go-Code die Summe von 10 Milliarden Zahlen aus, anstatt nur „erste Nachricht anzeigen: Hallo“?

Warum gibt mein Go-Code die Summe von 10 Milliarden Zahlen aus, anstatt nur „erste Nachricht anzeigen: Hallo“?

DDD
DDDOriginal
2024-10-28 07:49:02149Durchsuche

Why does my Go code print the sum of 10 billion numbers instead of just

Go-Parallelität und Kanalverwirrung

Problem

Ein Benutzer versucht, Go-Parallelität zu verstehen und Kanäle mithilfe des folgenden Codeausschnitts:

<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>

Die erwartete Ausgabe ist nur „erste Nachricht anzeigen: Hallo“, da die Hauptfunktion beendet werden sollte, sobald sie Daten vom Kanal empfängt. Die tatsächliche Ausgabe umfasst jedoch auch die Summe von 10 Milliarden Zahlen.

Antwort

Das Hauptproblem im Code besteht darin, dass der Scheduler frei zwischen den beiden Goroutinen wählen kann (Anzeige und Summe), die nicht gesperrt sind. Während der Programmierer erwartet, dass die Anzeige zuerst abgeschlossen wird und Daten an den Kanal gesendet werden, bevor die Summe abgeschlossen ist, geschieht dies möglicherweise aufgrund der nichtdeterministischen Natur des Planers nicht.

In einem möglichen Ausführungsszenario:

  1. main erstellt zwei Goroutinen für Anzeige und Summe.
  2. Der Scheduler wechselt sofort zur Anzeige.
  3. display druckt seine Nachricht und blockiert das Warten darauf, dass ein Empfänger die an den Kanal gesendeten Daten akzeptiert .
  4. Der Planer führt die Summe aus, anstatt die Anzeige fortzusetzen.
  5. sum berechnet und druckt die Summe von 10 Milliarden Zahlen.
  6. Der Planer entscheidet sich dafür, die Anzeige fortzusetzen, nachdem die Summe abgelaufen ist.
  7. Display sendet Daten an den Kanal.
  8. Der Scheduler wechselt zu Main, um die Daten vom Kanal zu empfangen.
  9. Main druckt die Summe und verlässt das Programm.

Um dieses Problem zu beheben und sicherzustellen, dass ausschließlich die Meldung „Erste Nachricht anzeigen: Hallo“ gedruckt wird, besteht ein Ansatz darin, einen Ergebniskanal zu verwenden, um die Nachricht von der Anzeige zu empfangen und das Programm sofort zu beenden. Die geänderte Hauptfunktion wäre:

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

    go display("hello", result)
    fmt.Println(<-result)
}</code>

Das obige ist der detaillierte Inhalt vonWarum gibt mein Go-Code die Summe von 10 Milliarden Zahlen aus, anstatt nur „erste Nachricht anzeigen: Hallo“?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn