Heim > Backend-Entwicklung > Golang > Warum erscheint Golangs ungepufferte Kanalausgabereihenfolge kontraintuitiv?

Warum erscheint Golangs ungepufferte Kanalausgabereihenfolge kontraintuitiv?

Mary-Kate Olsen
Freigeben: 2024-12-16 21:15:12
Original
314 Leute haben es durchsucht

Why Does Golang's Unbuffered Channel Output Order Seem Counterintuitive?

Kanalausgabereihenfolge in Golang verstehen

In Golang bieten ungepufferte Kanäle einen zuverlässigen Kommunikationsmechanismus zwischen Goroutinen. Allerdings kann ihre Ausgabereihenfolge manchmal verwirrend sein. Betrachten Sie den folgenden Code:

func main() {
  messages := make(chan string)
  go func() { messages <- "hello" }()
  go func() { messages <- "ping" }()
  msg := <-messages
  msg2 := <-messages
  fmt.Println(msg)
  fmt.Println(msg2)
}
Nach dem Login kopieren

Beim Ausführen dieses Codes wird stets „ping“ gefolgt von „hello“ ausgegeben. Dies mag kontraintuitiv erscheinen, da man erwarten könnte, dass die Ausgabe mit der Reihenfolge übereinstimmt, in der die Goroutinen erstellt wurden.

Um zu verstehen, warum dies geschieht, ist es wichtig, sich daran zu erinnern, dass Kanäle Kommunikationspipelines sind, während Goroutinen parallele Aufgaben darstellen. Die Ausführungsreihenfolge von Goroutinen ist nicht garantiert, selbst wenn sie in einer bestimmten Reihenfolge erstellt wurden.

In diesem Fall hat der Planer möglicherweise die Goroutine, die „Ping“ sendet, vor der Goroutine geplant, die „Hallo“ sendet. Wenn der erste Empfänger (d. h. msg := <-messages) verfügbar wird, akzeptiert er die Nachricht von der bereits geplanten „Ping“-Goroutine.

Nach dem Empfang der ersten Nachricht wird das Programm mit der Ausführung fortfahren bis der zweite Empfänger (msg2 := <-messages) verfügbar wird. Zu diesem Zeitpunkt ist die „Hallo“-Nachricht zum Senden bereit und wird als zweite Nachricht akzeptiert.

Daher wird die Ausgabereihenfolge durch die Ausführungsreihenfolge der Goroutinen bestimmt, die in den Kanal schreiben , nicht die Reihenfolge, in der sie erstellt werden, oder die Reihenfolge, in der die Nachrichten vom Kanal gelesen werden. Um dies zu überprüfen, kann man den Goroutinen eine Println-Anweisung hinzufügen, wie in der bereitgestellten Antwort vorgeschlagen:

...
func() { messages <- "hello"; fmt.Println("Hello sent") }()
func() { messages <- "ping"; fmt.Println("Ping sent") }()
...
Nach dem Login kopieren

Dies gibt Folgendes aus:

Hello sent
Ping sent
ping
hello
Nach dem Login kopieren

Dies bestätigt, dass die Nachrichten gesendet wurden und in der gleichen Reihenfolge gedruckt.

Das obige ist der detaillierte Inhalt vonWarum erscheint Golangs ungepufferte Kanalausgabereihenfolge kontraintuitiv?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage