Maison  >  Article  >  développement back-end  >  Modèle Fanin en Go

Modèle Fanin en Go

WBOY
WBOYoriginal
2024-07-28 15:17:33823parcourir

Fanin Pattern in Go

Jetons un coup d'œil au motif en éventail. Ceci est vraiment utile lorsque nous avons des données associées provenant de plusieurs threads que nous devons rassembler.

Par exemple, supposons que vous ayez effectué plusieurs appels d'API vers différents services et que vous deviez combiner les résultats.

Il s'agit d'un modèle très simple à mettre en œuvre, mais vous devez faire attention à la façon dont vous gérez les canaux. Il est facile de se retrouver dans une situation de blocage.

// produce is used to simulate the different data sources
func produce(id int) chan int {
    ch := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            ch <- id*10 + i
        }
        fmt.Printf("producer %d done\n", id)
        close(ch) // this is important!!!
    }()
    return ch
}

func fanin(inputs ...chan int) chan int {
    output := make(chan int)

    var wg sync.WaitGroup
    for i, input := range inputs {
        wg.Add(1)
        go func() {
            for value := range input {
                output <- value
            }
            fmt.Printf("done merging source %d\n", i)
            wg.Done()
        }()
    }
    go func() {
        wg.Wait()
        close(output) // this is important!!!
    }()

    return output
}

func main() {
    input1 := produce(0)
    input2 := produce(1)

    result := fanin(input1, input2)

    done := make(chan bool)
    go func() {
        for value := range result {
            fmt.Printf("got %d\n", value)
        }
        close(done)
    }()
    <-done
    fmt.Println("done")
}

Ici, nous utilisons la fonction produire pour simuler les différentes sources. Ces canaux sources sont envoyés à la fonction fanin qui effectue l'opération de combinaison.

La fonction fanin crée le canal de sortie, puis lance une goroutine qui opère sur chaque entrée. Nous utilisons un WaitGroup pour indiquer quand toutes les sources d'entrée ont été combinées dans le canal de sortie.

Dans cet exemple simple, le thread principal parcourt simplement la sortie. Attention il n'y a aucune garantie sur la commande, les valeurs des 2 entrées sont mélangées.

Un point clé à souligner est que nous devons fermer le canal de sortie lorsque nous avons fini de combiner les entrées. L'opérateur de plage attendra indéfiniment une fois que le canal sera vide. Commentez la ligne close(output) et vous verrez que vous obtenez une condition de blocage.

Comment pouvons-nous améliorer cela ? Laissez-moi un commentaire ci-dessous.

Merci !

Le code de cet article et de tous les articles de cette série peut être trouvé ici

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