Deadlock in Go: WaitGroup und gepufferte Kanäle
In Go tritt ein Deadlock auf, wenn gleichzeitige Goroutinen auf unbestimmte Zeit auf den Abschluss anderer warten. Eine häufige Ursache für Deadlocks ist die Verwendung von WaitGroups und gepufferten Kanälen.
Beispiel für einen Deadlock
Beachten Sie den folgenden Code:
<code class="go">package main import "fmt" import "sync" func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() ch <- m // Sending to a full channel return }() } wg.Wait() for c := range ch { fmt.Printf("c is %v", c) } }</code>
Dieser Code beabsichtigt, 5 leere Slices an einen gepufferten Kanal mit einer Kapazität von 4 zu senden und dann aus dem Kanal zu lesen, nachdem alle Goroutinen abgeschlossen sind. Der Code führt jedoch zu einem Deadlock-Fehler.
Ursache des Deadlocks
Der Deadlock entsteht aufgrund zweier Probleme:
Lösung
Um den Deadlock zu beheben, nehmen Sie eine der folgenden Änderungen vor:
Lösung 1:
Erhöhen Sie die Kanalkapazität auf 5 (oder mehr) und schließen Sie ihn, nachdem alle Daten gesendet wurden :
<code class="go">ch := make(chan []int, 5) ... wg.Wait() close(ch)</code>
Lösung 2:
Starten Sie eine separate Goroutine, um vom Kanal zu lesen und die Haupt-Goroutine zu benachrichtigen, wenn alle Daten empfangen wurden:
<code class="go">func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { ch <- m wg.Done() }() } go func() { for c := range ch { fmt.Printf("c is %v\n", c) wg.Done() } }() wg.Wait() }</code>
Das obige ist der detaillierte Inhalt vonWie kann ich einen Deadlock verhindern, wenn ich WaitGroups und gepufferte Kanäle in Go verwende?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!