Was sind Kanäle verwendet?
Beim Blick durch einige Go-code habe ich Folgendes gefunden:
ch := make(chan int)
Ich blickte in ein online-tutorial, wie Sie Gehen-Kanäle arbeiten:
https://tour.golang.org/concurrency/2
Aber ich finde dieses Beispiel unklar.
Kann mir jemand eine einfache Erklärung und ein Beispiel für die Nutzung der Kanäle?
Du musst angemeldet sein, um einen Kommentar abzugeben.
chan ist ein Kanal in Golang. In einfachen Wort, das Sie können denken, es als ein Feld, in dem du ein Element an einem Ende und dann Holen Sie es aus dem anderen Ende.
Ungepuffert-Kanäle
Gepufferten Kanal
Dies ist der kleine code, den ich geschrieben habe, für Sie zu verstehen, Kanäle. Ändern Sie jetzt, um von go-Routinen und sehen Sie die Ausgänge. Jedes mal, wenn die Ausgabe kann abweichen.
Für beste Verständnis besuchen dieses blog, in dem go-Routinen und-Kanäle beschrieben sind, die in GUI.
Besuchen http://divan.github.io/posts/go_concurrency_visualize/
Ich denke die Skillung ist ziemlich klar auf diesem. Spezifikation: Kanal-Typen:
Wenn Sie mehrere goroutines, die ausgeführt werden, gleichzeitig können die Kanäle bieten den einfachsten Weg, um die goroutines, um miteinander zu kommunizieren.
Einen Weg für die Kommunikation wäre über eine "shared" - variable, die sichtbar ist, um beide goroutines, aber das würde erfordern ordnungsgemäße Verriegelung /synchronisiert zugreifen.
Statt, Gehen favorisiert Kanäle. Zitat aus Effektiv Gehen: Teilen durch Kommunikation:
So, anstatt Nachrichten in einem freigegebenen Scheibe zum Beispiel, können Sie erstellen Sie einen Kanal (sichtbar für beide goroutines), und ohne externe Synchronisierung /locking, eine goroutine kann Nachrichten senden (Werte) über den Kanal, und die anderen goroutine kann Sie erhalten.
So, in der Tat, eine beliebige Anzahl von goroutine kann Werte senden auf dem gleichen Kanal, und eine beliebige Anzahl von goroutines können Werte erhalten aus, noch immer ohne jegliche weitere Synchronisierung. Siehe Verwandte Frage für weitere details: Wenn ich die Kanäle richtig muss ich Mutexe verwenden?
Kanal Beispiel:
Betrachten ein Beispiel, wo wir beginnen 2 zusätzliche goroutines für parallele Berechnungen geeignet. Wir passieren eine Reihe zu den ersten, die 1 addiert, und liefert das Ergebnis auf einen 2. Kanal. Der 2. goroutine erhalten eine Zahl, multipliziere es mit 10 und liefern Sie zu den Ergebnis-Kanal:
Dies ist, wie es aufgerufen werden kann /verwendet:
Kommunikation über die Kanäle kümmert sich auch um die goroutines auf einander warten. In diesem Beispiel bedeutet es
MulBy10()
warten, bisAddOne()
liefert den inkrementierten Zahl, undmain()
wartenMulBy10()
vor dem drucken das Ergebnis. Ausgang wie erwartet (versuchen Sie es auf die Gehen Spielplatz):Sprachunterstützung
Gibt es eine Reihe von Sprachmittel, die für die einfache Nutzung von Kanälen, zum Beispiel:
for ... range
auf einen Kanal durchläuft die Werte von einem Kanal, bis der Kanal geschlossen.select
- Anweisung kann verwendet werden, um die Liste mehrere channel-Operationen wie senden auf einem Kanal und erhalten aus einem Kanal, und die, die gehen können, ohne zu blockieren ausgewählt (zufällig, wenn es mehrere Einsen, die können gehen; und wird blockiert, wenn keiner bereit ist).v, ok := <-ch
len()
- Funktion teilt die Anzahl der Elemente in der Warteschlange (ungelesen); der builtingKappe()
Funktion gibt die Kanal-Puffer-Kapazität.Andere Verwendungen
Für eine mehr Praxis-Beispiel sehen Sie, wie die Kanäle können verwendet werden, um die Umsetzung einer worker pool. Eine ähnliche Nutzung ist die Verteilung der Werte aus einer Produzenten bis zum Verbraucher(s).
Einem anderen Beispiel aus der Praxis ist die Umsetzung einer der Speicher-pool mit gepufferten Kanälen.
Ist und noch ein Beispiel aus der Praxis ist eine elegante Umsetzung eines Maklers.
Einen Kanal wird Häufig verwendet, um timeout-einige blockierende operation, die Verwendung eines Kanals zurückgegeben
Zeit.Nach()
die "feuert" nach der angegebenen Verzögerung /Dauer ("feuert" bedeutet, dass ein Wert gesendet wird) zusammen. Siehe dieses Beispiel für die demonstration (versuchen Sie es auf die Gehen Spielplatz):Kann es verwendet werden, um zu warten, bis eine maximale Zeit, die Menge, die für einen gewissen Wert, aber wenn die anderen goroutines nicht liefern kann, wird der Wert durch die Zeit, wir können entscheiden, etwas anderes zu tun, statt.
Auch eine Besondere form der Kommunikation kann nur zu signal Fertigstellung einige Betrieb (ohne tatsächlich das senden aller "nützlichen" Daten). Ein solcher Fall implementiert werden kann, die durch einen Kanal mit einem element-Typ, z.B.
chan int
, und sendet einen beliebigen Wert an, z.B.0
. Aber da der gesendete Wert enthält keine Informationen, Sie können es erklären, wiechan struct{}
. Oder noch besser, wenn Sie nur eine einmalige Signalisierung, Sie können einfach schließen Sie die Sender, die abgehört werden können, auf der anderen Seite mitfor ... range
oder den Erhalt von es (wie das erhalten von einem geschlossenen Kanal Erlös sofort, woraus sich die null Wert der element-Typ). Wissen auch, dass, obwohl ein Kanal kann verwendet werden, für diese Art von Signal, es gibt eine bessere alternative: diesync.WaitGroup
.Weiter Lesen
Es lohnt sich zu wissen, über den Kanal Axiome zu vermeiden, überraschend Verhalten: Wie funktioniert eine nicht initialisiert-channel-Verhalten?
Die Go-Blog: Speicher Freigeben, Indem Die Kommunikation
Die Go-Blog: Gehen Parallelität Muster: Rohrleitungen und Stornierung
Die Go-Blog: Fortgeschrittene Gehen Parallelität-Muster
Ardan labs: Die Natur Der Kanäle Gehen