Heim >Backend-Entwicklung >Golang >Wie löst man Deadlocks in Go, wenn alle Goroutinen schlafen?
Deadlock in Go: „Alle Goroutinen schlafen“
Bei der Arbeit mit Goroutinen ist es wichtig, den Kanalbetrieb effektiv zu verwalten, um Deadlocks zu vermeiden. Dies geschieht, wenn alle Goroutinen auf unbestimmte Zeit blockiert sind, was zu einer Deadlock-Situation führt.
Den Code verstehen
Sehen wir uns den bereitgestellten Code an:
package main import ( "fmt" "sync" "time" ) type Item struct { name string } type Truck struct { Cargo []Item name string } func UnloadTrucks(c chan Truck) { for t := range c { fmt.Printf("%s has %d items in cargo: %s\n", t.name, len(t.Cargo), t.Cargo[0].name) } } func main() { trucks := make([]Truck, 2) ch := make(chan Truck) for i, _ := range trucks { trucks[i].name = fmt.Sprintf("Truck %d", i+1) fmt.Printf("Building %s\n", trucks[i].name) } for t := range trucks { go func(tr Truck) { itm := Item{} itm.name = "Groceries" fmt.Printf("Loading %s\n", tr.name) tr.Cargo = append(tr.Cargo, itm) ch <- tr }(trucks[t]) } time.Sleep(50 * time.Millisecond) fmt.Println("Unloading Trucks") UnloadTrucks(ch) fmt.Println("Done") }
Dieser Code erstellt einen Kanal-CH vom Typ Truck und startet zwei Goroutinen, um das Beladen von LKWs mit Lebensmitteln und deren Versand an den Kanal zu simulieren. Anschließend ruft es UnloadTrucks auf, um den Inhalt der LKWs abzurufen und auszudrucken.
Ursache des Deadlocks
Das Problem liegt im Fehlen eines Mechanismus zum Schließen des CH-Kanals. Wenn alle Goroutinen ihre LKWs an den Kanal gesendet haben, gibt es in UnloadTrucks kein Signal zum Beenden der Schleife. Das bedeutet, dass ch weiterhin auf Werte wartet, die nie eintreffen, was zu einem Deadlock führt.
Lösung
Um den Deadlock aufzulösen, müssen wir den Kanal ch explizit schließen, wenn Die Lade-Goroutinen sind abgeschlossen. Wir können eine sync.WaitGroup verwenden, um die laufenden Goroutinen zu zählen und den Kanal zu schließen, wenn alle fertig sind:
var wg sync.WaitGroup go func() { wg.Wait() close(ch) }() UnloadTrucks(ch)
Diese Änderung stellt sicher, dass UnloadTrucks beendet wird, sobald alle Goroutinen mit dem Beladen der LKWs fertig sind. Die Wait-Funktion blockiert, bis der WaitGroup-Zähler Null erreicht, was anzeigt, dass alle Goroutinen ihre Arbeit abgeschlossen haben. Das Schließen des Kanals signalisiert UnloadTrucks, dass keine weiteren LKWs mehr empfangen werden können, sodass die Schleife ordnungsgemäß verlassen werden kann.
Das obige ist der detaillierte Inhalt vonWie löst man Deadlocks in Go, wenn alle Goroutinen schlafen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!