Maison >développement back-end >Golang >Comment fermer gracieusement une chaîne Go de longueur inconnue ?

Comment fermer gracieusement une chaîne Go de longueur inconnue ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-24 11:20:16506parcourir

How to Gracefully Close a Go Channel of Unknown Length?

Déterminer quand fermer une chaîne sans connaître sa longueur

Lorsque vous travaillez avec des chaînes dans Go, il est crucial de déterminer le moment approprié pour les fermer. Cela présente un défi lorsque la longueur du canal est inconnue.

Considérons le scénario suivant :

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)

    go func() {
        for i := 0; i < 100; i++ {
            ch <- i
        }
        close(ch)
    }()

    for v := range ch {
        fmt.Println(v)
    }
}

Dans cet exemple, une goroutine envoie 100 valeurs au canal, avec l'intention de le fermer. une fois que toutes les valeurs ont été envoyées. Cependant, cette approche suscite des inquiétudes. Plus précisément :

  • Fermeture simultanée : Plusieurs goroutines peuvent tenter de fermer le canal simultanément, provoquant une panique.
  • Fermeture inattendue : Le goroutine principal peut se terminer avant que toutes les valeurs n'aient été reçues, ce qui entraîne la perte de certaines valeurs. abandonné.

Emploi d'un WaitGroup pour une fermeture gracieuse

Pour résoudre ces problèmes, un sync.WaitGroup peut être utilisé pour synchroniser la fermeture du canal avec l'achèvement de la goroutine d'envoi.

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    ch := make(chan int)

    wg.Add(1) // Increment counter for sender goroutine
    go func() {
        defer wg.Done() // Decrement counter when goroutine completes
        for i := 0; i < 100; i++ {
            ch <- i
        }
        close(ch)
    }()

    go func() {
        wg.Wait() // Wait until the sender goroutine completes
        close(ch) // Close the channel after all values have been sent
    }()

    for v := range ch {
        fmt.Println(v)
    }
}

Mise en œuvre Détails

  • WaitGroup : Le sync.WaitGroup nous permet de suivre le nombre de goroutines en cours d'exécution. Il garantit que la goroutine principale ne se termine pas tant que toutes les goroutines de l'expéditeur ne sont pas terminées.
  • Goroutine de fermeture séparée : La fermeture du canal est effectuée dans une goroutine dédiée. Cela garantit que la goroutine principale ne se fermera qu'après la lecture de toutes les données en attente dans le canal.
  • Expéditeurs multiples : Cette approche fonctionne également pour les scénarios avec plusieurs goroutines envoyant vers le même canal . Le sync.WaitGroup garantit que le canal est fermé uniquement une fois que toutes les goroutines de l'expéditeur ont fini d'envoyer des valeurs.

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