Maison > Article > développement back-end > Modèle Fanin en 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!