Deadlock im Parallelitätsmodell von Go: Verwendung ungepufferter Kanäle
Im Go-Parallelitätsmodell sind Kanäle ein grundlegender Mechanismus für die Kommunikation zwischen Goroutinen . Das Verhalten von Kanälen kann jedoch je nach Puffergröße variieren. Hier befassen wir uns mit einem Deadlock-Szenario, das bei der Verwendung ungepufferter Kanäle auftritt.
Das Problem
Bedenken Sie den folgenden Go-Codeausschnitt:
package main import "fmt" func main() { c := make(chan int) c <- 1 fmt.Println(<-c) }
Bei der Ausführung führt dieser Code zu a Deadlock:
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan send]: main.main() /path/to/file:8 +0x52 exit status 2
Erklärung
Der Deadlock tritt aufgrund der Verwendung eines ungepufferten Kanals auf. Ein ungepufferter Kanal erfordert, wie in der Dokumentation angegeben, die Anwesenheit eines Empfängers, bevor ein Wert gesendet werden kann. In diesem Fall wird der Kanal standardmäßig als ungepuffert initialisiert (mit einer Puffergröße von 0).
Wenn die Zeile c <- 1 ausgeführt wird, versucht die Goroutine, den Wert 1 auf den Kanal zu senden. Da der Kanal jedoch keinen Puffer hat, wartet er darauf, dass ein Empfänger den Wert abruft, bevor er fortfährt.
Gleichzeitig versucht die fmt.Println(<-c)-Anweisung, einen Wert vom Kanal zu empfangen. Da jedoch noch kein Wert gesendet wurde (da die Goroutine auf einen Empfänger wartet), blockiert die Empfangsoperation.
Dies führt zu einem Deadlock, da beide Goroutinen darauf warten, dass die andere eine Operation abschließt kann ohne den anderen funktionieren.
Lösung
Um den Deadlock zu lösen, muss man einen Empfänger für den Kanal einführen. Durch die Erstellung einer separaten Goroutine für den Empfang des gesendeten Werts kann der Deadlock beseitigt werden. Der untenstehende modifizierte Code demonstriert diese Lösung:
package main import "fmt" func main() { c := make(chan int) go func() { fmt.Println("received:", <-c) }() c <- 1 }
Das obige ist der detaillierte Inhalt vonWarum führt die Verwendung ungepufferter Kanäle in Go zu einem Deadlock?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!