Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann ein Deadlock vermieden werden, wenn Goroutinen zum Verarbeiten von Werten und zum Sammeln von Ergebnissen in einem Slice verwendet werden?

Wie kann ein Deadlock vermieden werden, wenn Goroutinen zum Verarbeiten von Werten und zum Sammeln von Ergebnissen in einem Slice verwendet werden?

DDD
DDDOriginal
2024-11-06 17:56:02969Durchsuche

How to Avoid Deadlock When Using Goroutines to Process Values and Gather Results into a Slice?

Verwendung von Goroutinen, um Werte effizient zu verarbeiten und Ergebnisse in einem Slice zu sammeln

Die Verwendung von Goroutinen kann ein transformatives Element in der Go-Programmierung sein und ermöglichen gleichzeitige Aufgabenausführung und effiziente Verarbeitung. Allerdings ist eine ordnungsgemäße Implementierung von entscheidender Bedeutung, um potenzielle Fallstricke zu vermeiden.

Problem:

Beim Versuch, Goroutinen in einer Codebasis einzusetzen, tritt ein „schwerwiegender Fehler: Alle Goroutinen schlafen“ auf. Deadlock!" entsteht. Ziel ist es, Werte in einer Liste gleichzeitig zu verarbeiten und die verarbeiteten Ergebnisse anschließend in einer neuen Liste zusammenzufassen. Schwierigkeiten treten jedoch in der Akkumulationsphase auf.

Codezerlegung:

Das bereitgestellte Code-Snippet enthält mehrere wesentliche Elemente:

// Process each item with a goroutine and send output to sampleChan
go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
  • Diese Goroutine verarbeitet die Daten gleichzeitig und sendet das Ergebnis an einen Kanal namens „sampleChan“.
// Read from sampleChan and put into a slice
for s := range sampleChan {
    sampleList = append(sampleList, s)
}
close(sampleChan)
  • Der Code versucht, Ergebnisse aus dem Kanal zu sammeln und sie in einen Slice zu integrieren.

Lösung:

Die Fehler werden durch zwei Probleme verursacht: vorzeitiges Warten auf die Fertigstellung des Workers und falsches Timing für die Kanalschließung. Die folgenden Änderungen beheben diese Probleme:

go func() {
    wg.Wait()
    close(sampleChan)
}()
  • Verschieben Sie die Schließung des Kanals, bis die Arbeiter fertig sind, indem Sie eine separate Goroutine initiieren.

Darüber hinaus sollten Sie für den stilistischen Zusammenhalt eine Umstrukturierung in Betracht ziehen newSample als synchrone Funktion für die Ergebnisproduktion, was zu folgendem Code führt:

for i, line := range contents {
    wg.Add(1)
    go func(line string) {
        defer wg.Done()
        sampleChan <- newSample(line, *replicatePtr, *timePtr)
    }(line)
}

Dieser überarbeitete Ansatz verbessert die Lesbarkeit des Codes, erleichtert das Testen und vereinfacht die Parallelitätsverwaltung, wodurch eine klare Identifizierung kritischer Vorgänge wie wg.Done( ).

Das obige ist der detaillierte Inhalt vonWie kann ein Deadlock vermieden werden, wenn Goroutinen zum Verarbeiten von Werten und zum Sammeln von Ergebnissen in einem Slice verwendet werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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