Heim > Backend-Entwicklung > Golang > Warum verursachen ungepufferte Kanäle in Go Deadlocks?

Warum verursachen ungepufferte Kanäle in Go Deadlocks?

Mary-Kate Olsen
Freigeben: 2024-12-21 17:31:11
Original
190 Leute haben es durchsucht

Why Do Unbuffered Channels in Go Cause Deadlocks?

Deadlock in ungepufferten Kanälen in Goroutinen

Im Parallelitätsmodell von Go können ungepufferte Kanäle zu unerwarteten Deadlocks führen. Lassen Sie uns untersuchen, warum dies geschieht, und eine alternative Lösung erkunden.

Betrachten Sie den folgenden Codeausschnitt:

package main

import "fmt"

func main() {
    c := make(chan int)    
    c <- 1   
    fmt.Println(<-c)
}
Nach dem Login kopieren

Dieser Code führt scheinbar einen einfachen Sende- und Empfangsvorgang auf einem ungepufferten Kanal aus. Bei der Ausführung kommt es jedoch zu einem Deadlock mit dem folgenden Fehler:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    /home/tarrsalah/src/go/src/github.com/tarrsalah/tour.golang.org/65.go:8 +0x52
exit status 2
Nach dem Login kopieren

Um zu verstehen, warum dieser Deadlock auftritt, müssen wir zunächst das Verhalten ungepufferter Kanäle verstehen.

Eintauchen in ungepufferte Kanäle

Wie in der offiziellen Dokumentation von Go dokumentiert: „Wenn der Kanal vorhanden ist ungepuffert blockiert der Sender, bis der Empfänger den Wert empfangen hat. Wenn der Kanal über einen Puffer verfügt, blockiert der Sender nur, bis der Wert in den Puffer kopiert wurde. Dies bedeutet, dass er wartet, bis ein Empfänger einen Wert abgerufen hat ."

Einfacher ausgedrückt:

  1. Ungepufferte Kanäle gelten als ständig voll.
  2. Senden von Daten an einen Der ungepufferte Kanal blockiert den Absender, bis eine andere Goroutine den Wert abruft.

Das Deadlock-Szenario

Im bereitgestellten Codeausschnitt blockiert die Operation c <- 1 weil der Kanal ungepuffert ist und keine andere Goroutine existiert, um den gesendeten Wert zu empfangen. Folglich kommt es zu einem Deadlock des Programms.

Den Deadlock durchbrechen

Um den Deadlock aufzulösen, können wir entweder:

  1. Verwenden Sie a Gepufferter Kanal: Durch Erstellen eines gepufferten Kanals (z. B. c := make(chan int, 1)) weisen wir einen kleinen Puffer zu, in dem Sender-Goroutinen vorübergehend Werte platzieren können, bevor ein Empfänger bereit ist.

ODER

  1. Führen Sie eine Empfangs-Goroutine ein: Wir können eine separate Goroutine einführen, um den Empfang von Daten vom Kanal zu verarbeiten. Dadurch wird sichergestellt, dass ein Verbraucher immer verfügbar ist, um gesendete Werte abzurufen.

Beispiel mit einer empfangenden Goroutine:

package main

import "fmt"

func main() {
    c := make(chan int)    
    go func() {
        fmt.Println("received:", <-c)
    }()
    c <- 1   
}
Nach dem Login kopieren

Hier die mit go erstellte Goroutine func() {...} wartet kontinuierlich darauf, Werte vom Kanal zu empfangen. Durch die Einführung dieser Empfangs-Goroutine wird der Deadlock verhindert.

Zusammenfassend lässt sich sagen, dass die Verwendung ungepufferter Kanäle in derselben Goroutine ohne einen dedizierten Empfangsmechanismus zu Deadlocks führen kann. Um dies zu vermeiden, sollten Sie erwägen, gepufferte Kanäle zu verwenden oder separate Empfangs-Goroutinen einzuführen, um eine ordnungsgemäße Datenübertragung zwischen gleichzeitigen Goroutinen sicherzustellen.

Das obige ist der detaillierte Inhalt vonWarum verursachen ungepufferte Kanäle in Go Deadlocks?. 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