Maison > Article > développement back-end > Comment éviter les impasses lors de la collecte des résultats des Goroutines ?
Utilisation de Goroutines pour le traitement des données
Dans Go, les goroutines sont des threads légers qui permettent l'exécution simultanée de tâches. Lorsque vous travaillez avec des goroutines, il est important de collecter correctement les résultats après le traitement pour éviter les blocages.
Énoncé du problème
Considérez l'extrait de code suivant :
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)
Ce code tente de traiter les éléments d'une liste à l'aide de goroutines et de rassembler les résultats dans une tranche. Cependant, il rencontre une erreur de blocage car le canal est fermé avant que les résultats ne soient collectés.
Solution
Pour résoudre ce problème, nous pouvons après tout fermer le canal de manière asynchrone les ouvriers ont fini le traitement. Voici le code corrigé :
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 { .. }
Ce code démarre des goroutines qui traitent les éléments et envoient les résultats à sampleChan. Parallèlement, il démarre également une autre goroutine qui attend que tous les travailleurs aient terminé, puis ferme le canal. Cela garantit que tous les résultats sont collectés avant la fermeture du canal.
Solution alternative
Pour une meilleure lisibilité et testabilité du code, il est recommandé d'utiliser une fonction newSample synchrone et de gérer la concurrence dans la goroutine principale.
for i, line := range contents { wg.Add(1) go func(line string) { defer wg.Done() sampleChan <- newSample(line, *replicatePtr, *timePtr) }(line) }
Cette approche maintient les primitives de concurrence localisées, simplifiant la maintenance du code et réduisant le risque d'erreurs.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!