Heim  >  Artikel  >  Backend-Entwicklung  >  Wie vermeidet man Deadlocks bei der Verwendung von Goroutinen für die parallele Verarbeitung und Ergebniserfassung?

Wie vermeidet man Deadlocks bei der Verwendung von Goroutinen für die parallele Verarbeitung und Ergebniserfassung?

Barbara Streisand
Barbara StreisandOriginal
2024-11-07 02:09:03484Durchsuche

How to Avoid Deadlocks When Using Goroutines for Parallel Processing and Result Gathering?

Goroutinen für die parallele Verarbeitung und Ergebniserfassung verstehen

Hintergrund

Ihr Ziel ist es, Goroutinen in Go zu nutzen, um Elemente parallel zu verarbeiten und ihre Ergebnisse zu sammeln in eine Scheibe schneiden. Sie sind jedoch auf einen verblüffenden Deadlock-Fehler gestoßen: „Alle Goroutinen schlafen – Deadlock!“

Lösung

Der Fehler ist auf zwei Probleme in Ihrem Code zurückzuführen:

  1. Verzögerte Erfassung:Sie warten darauf, dass alle Goroutinen abgeschlossen sind, bevor Sie Ergebnisse sammeln, was falsch ist.
  2. Vorzeitige Schließung des Kanals:Der Kanal wird nach der Ergebniserfassung geschlossen Schleife wird beendet, wodurch die Iteration vorzeitig beendet wird.

Überarbeiteter Code

Um diese Probleme zu beheben, führen Sie eine Goroutine ein, die den Kanal asynchron schließt, wenn die Arbeiter fertig sind:

for i, line := range contents {
  wg.Add(1)
  go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
}

go func() {
  wg.Wait()
  close(sampleChan)
}()

for s := range sampleChan {
  ..
}

Erklärung

  • Asynchrone Kanalschließung: Die anonyme Goroutine schließt den Kanal, nachdem alle Worker abgeschlossen sind, und vermeidet so eine vorzeitige Beendigung der Schleife.
  • Stilempfehlung : Erwägen Sie die Verwendung einer synchronen Hilfsfunktion (newSample), die den Kanal und die Wartegruppe nicht beansprucht, was den Code vereinfacht und die Testbarkeit verbessert.

Refactoring für Effizienz

Wenn Sie Wenn Sie für eine optimale Effizienz eine feste Anzahl von Workern benötigen, refaktorisieren Sie den Code wie folgt:

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

Dies hält die Parallelitätsprimitive zusammen und vereinfacht das Refactoring für verschiedene Parallelitätsmuster.

Das obige ist der detaillierte Inhalt vonWie vermeidet man Deadlocks bei der Verwendung von Goroutinen für die parallele Verarbeitung und Ergebniserfassung?. 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