Werfen wir einen Blick auf das Fan-In-Muster. Dies ist in Go wirklich nützlich, wenn wir verwandte Daten aus mehreren Threads haben, die wir zusammenführen müssen.
Angenommen, Sie haben mehrere API-Aufrufe an verschiedene Dienste durchgeführt und müssen die Ergebnisse kombinieren.
Dies ist ein wirklich einfach zu implementierendes Muster, aber Sie müssen darauf achten, wie Sie mit den Kanälen umgehen. Es kann leicht zu einem Deadlock-Zustand kommen.
// 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") }
Hier verwenden wir die Produce-Funktion, um die verschiedenen Quellen zu simulieren. Diese Quellkanäle werden an die Fanin-Funktion gesendet, die den Kombinationsvorgang ausführt.
Die Fanin-Funktion erstellt den Ausgabekanal und startet dann eine Goroutine, die jede Eingabe bearbeitet. Wir verwenden eine WaitGroup, um anzuzeigen, wann alle Eingabequellen im Ausgabekanal kombiniert wurden.
In diesem einfachen Beispiel iteriert der Hauptthread einfach über die Ausgabe. Beachten Sie, dass es keine Garantie für die Reihenfolge gibt, da die Werte der beiden Eingaben gemischt sind.
Ein wichtiger Punkt, den wir ansprechen müssen, ist, dass wir den Ausgabekanal schließen müssen, wenn wir mit der Kombination der Eingaben fertig sind. Der Bereichsoperator wartet unbegrenzt, sobald der Kanal leer ist. Kommentieren Sie die Schließzeile (Ausgabezeile) aus und Sie werden sehen, dass eine Deadlock-Bedingung vorliegt.
Wie können wir das verbessern? Hinterlassen Sie mir unten einen Kommentar.
Danke!
Den Code für diesen Beitrag und alle Beiträge dieser Reihe finden Sie hier
Das obige ist der detaillierte Inhalt vonFanin-Muster in Go. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!