Schaffen Sie weiter, beschleunigen Sie das Wachstum! Dies ist der sechste Tag meiner Teilnahme an der „Nuggets Daily New Plan · June Update Challenge“, klicken Sie hier, um die Details der Veranstaltung anzuzeigen
Kanal
Lassen Sie uns zunächst die Rolle des Kanals klären: Er wird für die Kommunikation zwischen go-Coroutinen verwendet.
Das größte Merkmal der Go-Sprache ist die Unterstützung für hohe Parallelität: Goroutinen und Kanäle sind ein wichtiger Bestandteil der Unterstützung für hohe Parallelität.
Es macht keinen Sinn, Funktionen einfach gleichzeitig auszuführen. Daten müssen zwischen Funktionen ausgetauscht werden, um die Bedeutung der gleichzeitigen Ausführung von Funktionen widerzuspiegeln.
Wenn eine Goroutine ein gleichzeitig ausgeführter Hauptteil eines Go-Programms ist, channel
ist sie die Verbindung zwischen ihnen. channel
Ein Kommunikationsmechanismus, der es einer Goroutine ermöglicht, bestimmte Werte an eine andere Goroutine zu senden.
Darüber hinaus müssen Sie die Concurrency-Philosophie von go genau kennen und dieses Prinzip im Hinterkopf behalten: Verwenden Sie Kommunikation, um Speicher zu teilen, verwenden Sie keinen gemeinsamen Speicher, um zu kommunizieren.
Nachdem wir die Rolle des Kanals herausgefunden haben, wollen wir die Eigenschaften von gqueue im GoFrame-Framework (im Folgenden als gf bezeichnet) untersuchen.
warten
Konzept
Warteschlange gqueue Gleichzeitig sichere Warteschlange mit dynamischer Größe
gqueue kann auch auf eine Warteschlange mit fester Größe eingestellt werden, was sich nicht vom Standardbibliothekskanal unterscheidet, wenn die Größe fest ist.
Einfach ausgedrückt, die von channel implementierte Funktion kann auch von gqueue implementiert werden.
zu verwendende Szenen:
gqueue ist nebenläufigkeitssicher und wird häufig in Szenarien verwendet, in denen mehrere Goroutinen Daten kommunizieren und dynamische Warteschlangengrößen unterstützen
Code-Demo
package main
import (
"fmt"
"github.com/gogf/gf/container/gqueue"
"github.com/gogf/gf/os/gtimer"
"time"
)
func main() {
//实例化gqueue
q := gqueue.New()
//数据生产者 每隔1秒想队列写入1条数据
gtimer.SetInterval(time.Second, func() {
nowStr := time.Now().String()
q.Push(nowStr)
})
//3秒后关闭队列
gtimer.SetTimeout(time.Second*3, func() {
fmt.Println("关闭队列")
q.Close()
})
// 消费者 不停的从队列中取值输出到终端中
for {
if v := q.Pop(); v != nil {
fmt.Println("消费者接收:", v)
} else {
break
}
}
}
复制代码
Ergebnis drucken
Vorteil
Warum nicht den Kanal der Standardbibliothek verwenden, sondern gqueue verwenden?
-
Die Verwendung von gqueue ist flexibler als Kanal, Kanal hat eine Begrenzung der Warteschlangengröße und gqueue-Warteschlange unterstützt dynamische Größe
-
Die Lese- und Schreibleistung des Kanals ist zwar sehr hoch, aber der Speicher muss initialisiert werden, wenn der Kanal erstellt wird, und die Effizienz des Initialisierungsvorgangs ist sehr gering, während die Erstellungseffizienz von gqueue sehr hoch ist und gqueue Speicher dynamisch erstellt .
Low-Level-Implementierung
Die zugrunde liegende Implementierung von gqueue basiert auf der dynamischen Größe von glist. Das Lesen von Daten wird blockiert, wenn die Warteschlange voll oder die Warteschlange leer ist.
Glist ist ein parallelitätssicherer Link, der das Deaktivieren der parallelitätssicheren Funktion unterstützt. Wenn die parallelitätssichere Funktion deaktiviert ist, ist sie dasselbe wie eine gewöhnliche verknüpfte Liste, und es gibt keine Blockierung beim Speichern und Lesen von Daten.
verhindern, dass der Prozess zerstört wird
Die Rolle von select{} kann verhindern, dass der Prozess zerstört wird
package main
import (
"fmt"
"github.com/gogf/gf/container/gqueue"
"github.com/gogf/gf/os/gtime"
"github.com/gogf/gf/os/gtimer"
"time"
)
func main() {
//实例化队列
queue := gqueue.New()
// 生产者每隔1秒钟向队列写入一条数据
gtimer.SetInterval(time.Second, func() {
queue.Push(gtime.Now().String())
})
//消费者 常驻内存一直接收生产者的数据
for {
select {
case v := <-queue.C: //C是 chan interface{}
if v != nil {
fmt.Println("消费者:", v)
} else {
return
}
}
}
}
复制代码
Operationsergebnis
Wie in der Abbildung unten gezeigt, kann select{} verhindern, dass der Prozess zerstört wird, gtimer hat Daten produziert und select in der for-Schleife hat Daten verbraucht.
Zusammenfassen
Durch diesen Artikel kennen wir das Konzept und die Rolle des Kanals. Ich kenne auch die zugrunde liegende Implementierung und Eigenschaften von gqueue sowie den Vergleich zwischen gqueue und channel. Welche Eigenschaften haben beide.
zu guter Letzt
Danke fürs Lesen und heiße alle willkommen: like, favorite,Münze(konzentrieren Sie sich auf)! ! !