Go-Parallelität und Kanalverwirrung behoben
Bei der Arbeit mit Parallelität in Go spielen Kanäle eine zentrale Rolle bei der Kommunikation zwischen Goroutinen. Ihr Verhalten kann jedoch manchmal zu Verwirrung führen.
Betrachten Sie das folgende Go-Programm:
<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>
Das beabsichtigte Verhalten besteht darin, dass das Programm „erste Nachricht anzeigen: Hallo“ ausgibt und dann beendet wird . Die tatsächliche Ausgabe enthält jedoch das Ergebnis der Summenfunktion:
display first message: hello 10000000000
Erklärung
Die Verwirrung entsteht durch die Tatsache, dass die Haupt-Goroutine-Blöcke auf der Zeile sind:
<code class="go"><-c</code>
Das bedeutet, dass die Haupt-Goroutine die Ausführung nicht fortsetzen kann, bis sie einen Wert von Kanal c erhält. Sowohl display als auch sum senden einen wahren Wert an c, wodurch die Haupt-Goroutine entsperrt wird. Der Planer kann jedoch auswählen, welche Goroutine zuerst ausgeführt werden soll.
Mögliche Ausführungsreihenfolge:
Lösung
Um sicherzustellen, dass die Wenn das Programm nur das erste Ergebnis ausgibt, können wir einen Ergebniskanal verwenden:
<code class="go">func display(msg string, result chan string) { result <- msg }</code>
Und die Hauptfunktion ändern in:
<code class="go">func main() { result := make(chan string) go display("hello", result) fmt.Println(<-result) }</code>
Das obige ist der detaillierte Inhalt vonGo-Parallelität: Warum druckt mein Programm unerwartete Ausgaben, wenn es Kanäle verwendet?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!