Heim >Backend-Entwicklung >Golang >Warum ist die Ausgabereihenfolge der ungepufferten Kanäle von Go nicht deterministisch?

Warum ist die Ausgabereihenfolge der ungepufferten Kanäle von Go nicht deterministisch?

DDD
DDDOriginal
2024-12-07 11:03:12269Durchsuche

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

Ausgabereihenfolge des Golang-Kanals: Ein tieferer Einblick

Die Reihenfolge zu verstehen, in der Nachrichten von einem Kanal empfangen werden, kann in Go etwas schwierig sein . Lassen Sie uns in den von Ihnen bereitgestellten Code eintauchen:

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

Die folgende Erklärung geht auf Ihre Bedenken ein und vermittelt ein klareres Verständnis dessen, was passiert:

Erstens ist es wichtig zu verstehen, dass Blockierungsvorgänge, wie z Das Senden oder Empfangen über ungepufferte Kanäle ist keine Garantie für eine Bestellung. In Go erfolgt die Goroutine-Ausführung gleichzeitig und es gibt standardmäßig keine definierte Reihenfolge für die Goroutine-Ausführung.

Wenn die erste Goroutine versucht, „Hallo“ an den Kanal zu senden und derzeit kein Empfänger wartet, wartet die Goroutine blockiert. Wenn die zweite Goroutine versucht, „Ping“ zu senden, wird sie ebenfalls blockiert.

Wenn nun die msg := <-messages-Anweisung erreicht wird, entsperrt das Programm willkürlich eine der blockierten Goroutinen. Die von dieser entsperrten Goroutine gesendete Nachricht wird in msg empfangen.

Der gleiche Vorgang findet für msg2 := <-messages statt. Eine andere Goroutine wird entsperrt und die von dieser Goroutine gesendete Nachricht wird in msg2 empfangen.

Die Reihenfolge, in der Goroutinen entsperrt werden und ihre Nachrichten in Nachrichten übertragen, ist nicht deterministisch. Aus diesem Grund wird immer „ping“ vor „hello“ angezeigt, obwohl Sie davon ausgegangen sind, dass die Routinen alternativ hätten ausgeführt werden sollen.

Um dies zu bestätigen, können Sie versuchen, print-Anweisungen zu den Goroutinen hinzuzufügen:

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

Wenn Sie den Code mehrmals ausführen, werden Sie feststellen, dass die Reihenfolge der Druckanweisungen aus den Goroutinen variieren kann. Dies zeigt weiter die nichtdeterministische Natur der Goroutinen-Ausführung.

Zusammenfassend lässt sich sagen, dass die Reihenfolge der Ausgabe eines Kanals in ungepufferten Kanälen nicht garantiert ist und von der Reihenfolge abhängt, in der die entsprechenden Goroutinen entsperrt werden.

Das obige ist der detaillierte Inhalt vonWarum ist die Ausgabereihenfolge der ungepufferten Kanäle von Go nicht deterministisch?. 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