Verwendung von Goroutinen für die Datenverarbeitung
In Go sind Goroutinen leichtgewichtige Threads, die die gleichzeitige Ausführung von Aufgaben ermöglichen. Bei der Arbeit mit Goroutinen ist es wichtig, die Ergebnisse nach der Verarbeitung ordnungsgemäß zu erfassen, um Deadlocks zu vermeiden.
Problemstellung
Beachten Sie den folgenden Codeausschnitt:
sampleChan := make(chan sample) var wg sync.WaitGroup // Read from contents list for i, line := range contents { wg.Add(1) // Process each item with a goroutine and send output to sampleChan go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg) } wg.Wait() // Read from sampleChan and put into a slice var sampleList []sample for s := range sampleChan { sampleList = append(sampleList, s) } close(sampleChan)
Dieser Code versucht, Elemente in einer Liste mithilfe von Goroutinen zu verarbeiten und die Ergebnisse in einem Slice zusammenzufassen. Es tritt jedoch ein Deadlock-Fehler auf, da der Kanal geschlossen wird, bevor die Ergebnisse erfasst werden.
Lösung
Um dieses Problem zu beheben, können wir den Kanal doch asynchron schließen Die Arbeiter haben die Bearbeitung abgeschlossen. Hier ist der korrigierte Code:
for i, line := range contents { wg.Add(1) // Process each item with a goroutine and send output to sampleChan go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg) } go func() { wg.Wait() close(sampleChan) }() for s := range sampleChan { .. }
Dieser Code startet Goroutinen, die Elemente verarbeiten und Ergebnisse an sampleChan senden. Gleichzeitig startet es auch eine weitere Goroutine, die darauf wartet, dass alle Arbeiter fertig sind, und dann den Kanal schließt. Dadurch wird sichergestellt, dass alle Ergebnisse erfasst werden, bevor der Kanal geschlossen wird.
Alternative Lösung
Für eine bessere Lesbarkeit und Testbarkeit des Codes wird empfohlen, eine synchrone newSample-Funktion und ein synchrones newSample-Handle zu verwenden die Parallelität in der Haupt-Goroutine.
for i, line := range contents { wg.Add(1) go func(line string) { defer wg.Done() sampleChan <- newSample(line, *replicatePtr, *timePtr) }(line) }
Dieser Ansatz hält Parallelitätsprimitive lokalisiert und vereinfacht so die Codepflege und Reduzierung des Fehlerrisikos.
Das obige ist der detaillierte Inhalt vonWie vermeidet man Deadlocks beim Sammeln von Ergebnissen aus Goroutinen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!