Maison >développement back-end >Golang >Comment fermer en toute sécurité un canal de longueur inconnue en Go ?

Comment fermer en toute sécurité un canal de longueur inconnue en Go ?

Patricia Arquette
Patricia Arquetteoriginal
2024-12-23 17:44:14438parcourir

How to Safely Close a Channel of Unknown Length in Go?

Fermeture d'un canal de longueur inconnue

Dans le code fourni, l'erreur "envoyer sur un canal fermé" se produit car plusieurs goroutines tentent d'envoyer valeurs sur un canal déjà fermé. Ce problème vient du manque de synchronisation entre les goroutines, car une goroutine ferme le canal tandis que d'autres envoient toujours des données.

Pour fermer efficacement un canal dans cette situation, il est essentiel de déterminer quand toutes les goroutines émettrices ont accompli leurs tâches. Ceci peut être réalisé en utilisant un sync.WaitGroup pour détecter quand toutes les goroutines de l'expéditeur ont fini d'envoyer des valeurs.

Voici le code modifié qui utilise un sync.WaitGroup :

func gen(ch chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    var i int
    for {
        time.Sleep(time.Millisecond * 10)
        ch <- i
        i++
        // when no more data (e.g. from db, or event stream)
        if i > 100 {
            break
        }
    }
}

func receiver(ch chan int) {
    for i := range ch {
        fmt.Println("received:", i)
    }
}

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

    for i := 0; i < 10; i++ {
        wg.Add(1)
        go gen(ch, wg)
    }

    go func() {
        wg.Wait()
        close(ch)
    }()

    receiver(ch)
}

Dans cette solution, chaque goroutine d'expéditeur en ajoute un au sync.WaitGroup pour indiquer qu'il enverra des valeurs sur le canal. Le wg.Wait() dans la goroutine close() garantit que le canal est fermé seulement une fois que toutes les goroutines de l'expéditeur ont terminé leurs tâches, évitant ainsi l'erreur « envoyer sur un canal fermé ».

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