Maison > développement back-end > Golang > le corps du texte

Comment pouvons-nous multiplexer correctement plusieurs canaux Go pour éviter les conditions de concurrence et la perte de données ?

Patricia Arquette
Libérer: 2024-11-23 16:42:18
original
125 Les gens l'ont consulté

How Can We Correctly Multiplex Multiple Go Channels to Avoid Race Conditions and Data Loss?

Multiplexage des canaux

Cet article aborde une fonction de multiplexeur destinée à fusionner les sorties d'un tableau de canaux en un seul canal. Cependant, l'implémentation fournie présente plusieurs problèmes qui entravent sa fonctionnalité.

Le code d'origine :

func Mux(channels []chan big.Int) chan big.Int {
    // Count down as each channel closes. When hits zero - close ch.
    n := len(channels)
    // The channel to output to.
    ch := make(chan big.Int, n)

    // Make one go per channel.
    for _, c := range channels {
        go func() {
            // Pump it.
            for x := range c {
                ch <- x
            }
            // It closed.
            n -= 1
            // Close output if all closed now.
            if n == 0 {
                close(ch)
            }
        }()
    }
    return ch
}
Copier après la connexion

Erreurs dans l'implémentation :

Fermeture à partir de plusieurs goroutines : La variable n est partagée entre plusieurs goroutines et est mise à jour par chaque goroutine lorsqu'elle détecte une fermeture de canal. Cela peut entraîner des conditions de concurrence et un comportement inattendu lorsque plusieurs goroutines tentent d'accéder et de mettre à jour n simultanément.

Capture de canal incorrecte : Les goroutines créées dans la boucle capturent chacune le même canal (le dernier élément des canaux) car c se voit attribuer la valeur du canal à chaque itération, plutôt que d'être transmis à la fonction goroutine.

Résolu Problèmes :

Pour résoudre ces problèmes, le code modifié utilise des techniques plus sûres :

Utilisation d'un WaitGroup : Un sync.WaitGroup est utilisé pour suivre l'achèvement de goroutines. Chaque goroutine signale au WaitGroup lorsqu'elle a fini de pomper les données, et la goroutine principale attend que toutes les goroutines soient terminées avant de fermer le canal de sortie.

Capture correcte du canal : Chaque goroutine passe le canal il doit écouter dans une fonction lambda, garantissant que chaque goroutine surveille correctement le canal qui lui est attribué.

Amélioré Sortie : Le code modifié produit la sortie attendue, où tous les canaux contribuent au canal de sortie dans une distribution uniforme. L'alimentation séquentielle observée dans la sortie d'origine est éliminée.

Considérations supplémentaires :

  • En l'absence d'un mécanisme de contrôle de concurrence, l'utilisation de GOMAXPROCS != 1 pourrait exacerber le problème de l'accès aux variables partagées, conduisant à des résultats inattendus.
  • L'approche WaitGroup garantit que le canal de sortie est fermé uniquement lorsque toutes les données de tous les canaux ont été traitées. Sans WaitGroup, la goroutine principale pourrait fermer le canal de sortie prématurément, entraînant une perte de données.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal