Heim  >  Artikel  >  Backend-Entwicklung  >  Wie vermeide ich Deadlocks beim Sammeln von Ergebnissen aus Goroutinen in Go?

Wie vermeide ich Deadlocks beim Sammeln von Ergebnissen aus Goroutinen in Go?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-07 12:56:03673Durchsuche

How to Avoid Deadlocks When Gathering Results from Goroutines in Go?

Verwenden von Goroutinen zum Verarbeiten von Werten und Sammeln von Ergebnissen in einem Slice

Goroutinen sind ein grundlegendes Konzept in Go für die gleichzeitige Programmierung. Sie ermöglichen die gleichzeitige Ausführung mehrerer Aufgaben, ohne den Hauptthread zu blockieren. Die Verwendung von Goroutinen kann jedoch schwierig sein, insbesondere wenn es darum geht, Ergebnisse aus mehreren Goroutinen zu sammeln.

Problemstellung

Ein Entwickler hat versucht, Goroutinen zu verwenden, um eine Liste von zu verarbeiten Elemente und sammeln die verarbeiteten Werte in einem Slice. Allerdings stießen sie auf das gefürchtete „Alle Goroutinen schlafen – Deadlock!“ Fehler.

Ursache des Deadlocks

Der Deadlock trat auf, weil der Code darauf wartete, dass alle Goroutinen die Verarbeitung abgeschlossen hatten, bevor er versuchte, die Ergebnisse zu sammeln. Dies führte zu einer Situation, in der die Goroutinen darauf warteten, dass das Slice zum Schreiben verfügbar war, während der Hauptthread darauf wartete, dass die Goroutinen die Verarbeitung beendeten.

Lösung

Um den Deadlock aufzulösen, muss das asynchrone Schließen des Kanals eingeführt werden, der für die Kommunikation zwischen den Goroutinen und dem Hauptthread verwendet wird. Der geänderte Code unten zeigt die Lösung:

// ...

// Create a channel to receive the processed values
sampleChan := make(chan sample)

var wg sync.WaitGroup

// Process each item in the list with a goroutine
for i, line := range contents {
    wg.Add(1)
    go func(line string) {
        defer wg.Done()
        // Process the item and send the result on the channel
        sampleChan <- newSample(line, *replicatePtr, *timePtr)
    }(line)
}

// Asyncronously close the channel when all goroutines are done
go func() {
    wg.Wait()
    close(sampleChan)
}()

// Read from the channel and gather results into a slice
var sampleList []sample
for s := range sampleChan {
    sampleList = append(sampleList, s)
}

// ...

Durch das asynchrone Schließen des Kanals kann der Hauptthread mit dem Sammeln der Ergebnisse fortfahren, selbst während die Goroutinen noch verarbeiten. Dadurch wird der Deadlock aufgehoben und die korrekte Ausführung des Codes ermöglicht.

Zusätzliche Überlegungen

Es ist erwähnenswert, dass diese Lösung zwar den Deadlock behebt, aber keine vollständige Lösung ist für die Verwaltung der Parallelität in diesem speziellen Szenario. Abhängig von den Anforderungen und der Anzahl der Goroutinen können zusätzliche Synchronisierungs- und Fehlerbehandlungsmechanismen erforderlich sein, um die Zuverlässigkeit und Korrektheit des Codes sicherzustellen.

Das obige ist der detaillierte Inhalt vonWie vermeide ich Deadlocks beim Sammeln von Ergebnissen aus Goroutinen in Go?. 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