Maison  >  Article  >  développement back-end  >  Comment éviter les blocages lors de l'utilisation de Goroutines pour traiter des valeurs et rassembler les résultats dans une tranche ?

Comment éviter les blocages lors de l'utilisation de Goroutines pour traiter des valeurs et rassembler les résultats dans une tranche ?

DDD
DDDoriginal
2024-11-06 17:56:02969parcourir

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

Utiliser les goroutines pour traiter efficacement les valeurs et rassembler les résultats en une seule tranche

L'utilisation des goroutines peut être un élément transformateur dans la programmation Go, permettant exécution simultanée de tâches et traitement efficace. Cependant, une mise en œuvre appropriée est cruciale pour éviter les pièges potentiels.

Problème :

Lors de la tentative d'emploi de goroutines dans une base de code, une « erreur fatale : toutes les goroutines sont endormies – impasse!" surgit. L'objectif est de traiter simultanément les valeurs d'une liste, puis d'accumuler les résultats traités dans une nouvelle liste. Des difficultés apparaissent cependant dans la phase d'accumulation.

Décomposition du code :

L'extrait de code fourni comprend plusieurs éléments essentiels :

// Process each item with a goroutine and send output to sampleChan
go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
  • Cette goroutine traite simultanément les données et envoie le résultat à un canal nommé sampleChan.
// Read from sampleChan and put into a slice
for s := range sampleChan {
    sampleList = append(sampleList, s)
}
close(sampleChan)
  • Le code tente de rassembler les résultats du canal et de les incorporer dans une tranche.

Solution :

Les erreurs sont causées par deux problèmes : une attente prématurée de l'achèvement du travailleur et un timing de fermeture de canal incorrect. Les modifications suivantes résolvent ces problèmes :

go func() {
    wg.Wait()
    close(sampleChan)
}()
  • Reportez la fermeture des chaînes jusqu'à ce que les travailleurs aient terminé en lançant une goroutine distincte.

De plus, pour la cohésion stylistique, envisagez une restructuration newSample en tant que fonction synchrone pour la production de résultats, aboutissant au code suivant :

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

Cette approche révisée améliore la lisibilité du code, facilite les tests et simplifie la gestion de la concurrence, permettant une identification claire des opérations critiques comme wg.Done( ).

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn