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) }
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
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:
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:
ODER
Beispiel mit einer empfangenden Goroutine:
package main import "fmt" func main() { c := make(chan int) go func() { fmt.Println("received:", <-c) }() c <- 1 }
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!