Heim > Backend-Entwicklung > Golang > Wie vermeidet man Deadlocks beim Sammeln von Ergebnissen aus Goroutinen?

Wie vermeidet man Deadlocks beim Sammeln von Ergebnissen aus Goroutinen?

Patricia Arquette
Freigeben: 2024-11-06 14:22:02
Original
719 Leute haben es durchsucht

How to Avoid Deadlocks When Gathering Results from Goroutines?

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)
Nach dem Login kopieren

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 {
  ..
}
Nach dem Login kopieren

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)
}
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage