Maison >développement back-end >Golang >Pourquoi est-ce que je reçois toujours des valeurs d'un canal Go fermé ?
Valeurs inattendues des canaux fermés
Dans Go, les canaux sont une puissante primitive de communication qui facilite l'échange de données entre les goroutines. Cependant, leur comportement peut parfois prêter à confusion, notamment concernant les canaux fermés.
La question :
Un développeur rencontre un comportement inattendu lorsqu'il tente de lire les valeurs d'un canal fermé. Même si le canal est explicitement fermé, ils continuent de recevoir les valeurs de l'instruction range. La question se pose : pourquoi ?
L'explication :
Selon la spécification du langage de programmation Go, la fermeture d'un canal implique qu'aucune autre valeur ne sera envoyée. Cependant, il est important de noter que toutes les valeurs précédemment envoyées peuvent toujours être reçues. La spécification indique qu'après avoir appelé close, "les opérations de réception renverront des valeurs nulles pour le type de canal sans blocage."
L'exemple :
Dans l'exemple de code fourni, des goroutines sont générées pour envoyer des valeurs dans le canal. Une fois toutes les valeurs envoyées, le canal est fermé à l'aide de la fonction close(). L'instruction range est ensuite utilisée pour parcourir les valeurs du canal.
Le comportement inattendu :
Malgré la fermeture du canal, l'instruction range parcourt les 5 valeurs envoyées. . Cela se produit car il y a encore 5 valeurs précédemment envoyées dans le tampon du canal avant sa fermeture. La fonction close() ne supprime pas immédiatement ces valeurs ; au lieu de cela, il signale qu'aucune autre valeur ne sera envoyée.
La solution :
Pour s'assurer qu'aucune valeur n'est reçue après la fermeture d'un canal, il est important d'attendre pour que toutes les opérations de réception en attente soient terminées. Ceci peut être réalisé en utilisant un mécanisme de synchronisation, tel qu'un WaitGroup, pour attendre que toutes les goroutines susceptibles d'envoyer des valeurs au canal se terminent.
Remarque supplémentaire :
L'astuce "time.Sleep" utilisée dans l'exemple de code d'origine était destinée à donner le temps à toutes les goroutines de terminer et au canal de se fermer avant de parcourir ses valeurs. Cependant, cette approche n’est pas fiable car elle repose sur un temps de sommeil arbitraire. Au lieu de cela, s'appuyer sur un mécanisme de synchronisation est plus robuste.
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!