Maison >développement back-end >Golang >Pourquoi My Go sync.WaitGroup ne se termine-t-il jamais ?

Pourquoi My Go sync.WaitGroup ne se termine-t-il jamais ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-27 04:57:14356parcourir

Why Doesn't My Go sync.WaitGroup Ever Complete?

Golang sync.WaitGroup Never Completes

Le code fourni démontre la concurrence en récupérant une liste d'URL et en téléchargeant et en enregistrant conditionnellement des fichiers dans le fichier système. La goroutine principale attend que tous les fichiers soient récupérés à l'aide d'un sync.WaitGroup. Cependant, le programme ne parvient pas à se fermer même après avoir terminé toutes les requêtes.

Pour comprendre le problème, considérez la fonctionnalité de WaitGroup. Il tient à jour le décompte des goroutines en cours d'exécution. Si le décompte atteint jamais zéro, le groupe d'attente revient immédiatement, indiquant que toutes les goroutines ont terminé leur exécution.

Dans le code donné, la méthode Add de WaitGroup est utilisée pour incrémenter le décompte, tandis que la méthode Done est utilisée pour le décrémenter. . Si la méthode Add est appelée plus de fois que la méthode Done, ou vice versa, le WaitGroup n'atteindra jamais zéro, ce qui obligera la goroutine principale à attendre indéfiniment.

Il y a deux erreurs dans le code fourni :

  1. La fonction downloadFromURL reçoit une copie du WaitGroup, pas un pointeur vers celui-ci. Cela entraîne la transmission d'une copie des données internes du WaitGroup, de sorte que toutes les modifications qui y sont apportées au sein de la fonction (telles que l'appel de Done) ne sont pas visibles par la goroutine principale. Pour résoudre ce problème, transmettez plutôt un pointeur vers WaitGroup :
func main() {
    ...
    go downloadFromURL(url, &wg)
    ...
}
  1. L'instruction defer wg.Done() n'est pas placée comme première instruction dans la fonction downloadFromURL. Si une erreur se produit ou si toute autre logique est exécutée avant d'appeler Done, l'opération de décrémentation ne sera pas enregistrée et le compte du WaitGroup n'atteindra jamais zéro. Pour résoudre ce problème, assurez-vous que defer wg.Done() est la première instruction de la fonction :
func downloadFromURL(url string, wg *sync.WaitGroup) error {
    defer wg.Done()
    ...
}

Avec ces corrections en place, le WaitGroup fonctionnera correctement, en décrémentant son décompte à mesure que les goroutines terminent leur tâches, menant finalement à la sortie réussie du goroutine principal.

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