Heim >Backend-Entwicklung >Golang >Detaillierte Erklärung des Golang-Kanals Chan
Die Kolumne Golang-Tutorial stellt Ihnen Golang über den Kanal Chan vor. Ich hoffe, dass sie Freunden, die es brauchen, hilfreich sein wird!
Schauen wir uns zunächst Threads an, die auf Golang auch Goroutine genannt werden.
Bevor wir diesen Artikel lesen, müssen wir Parallelität und Parallelität verstehen. Golangs Thread ist ein Parallelitätsmechanismus, keine Parallelität. Sie können im Internet nach den Unterschieden suchen. Es gibt viele Einführungen online.
Schauen wir uns zuerst ein Beispiel an
import( "fmt" ) funcmain(){ go fmt.Println("1") fmt.Println("2") }
In Golang können Sie einen Thread erstellen, indem Sie das Schlüsselwort go gefolgt von einer Funktion verwenden. Die letztere Funktion kann eine vorab geschriebene Funktion oder eine anonyme Funktion sein. Der obige Code erstellt eine anonyme Funktion und übergibt außerdem einen Parameter i. Das i in Klammern unten ist der tatsächliche Parameter a ein formaler Parameter.
funcmain(){ var i=3 go func(a int) { fmt.Println(a) fmt.Println("1") }(i) fmt.Println("2")}Ich habe am Ende nur eine Codezeile hinzugefügt, um den Hauptthread eine Sekunde lang in den Ruhezustand zu versetzen, und das Programm druckt nacheinander 2, 3 und 1 aus.
Warum passiert das also? Da das Programm zuerst den Hauptthread ausführt, wird das Programm nach Abschluss der Ausführung des Hauptthreads sofort beendet, sodass keine zusätzliche Zeit für die Ausführung des untergeordneten Threads verbleibt. Wenn Sie den Hauptthread am Ende des Programms 1 Sekunde lang ruhen lassen, hat das Programm genügend Zeit, den untergeordneten Thread auszuführen.
Der Thread endet hier, werfen wir einen Blick auf den Kanal.
Kanal wird auch Kanal genannt. Wie der Name schon sagt, besteht die Funktion des Kanals darin, Daten zwischen mehreren Threads zu übertragen.
chonlywrite := make(chan<- int) // Erstellen Sie einen schreibgeschützten Kanal. Schreibkanal.
Schauen wir uns ein Beispiel an:import( "fmt" "time" )funcmain(){ var i = 3 go func(a int) { fmt.Println(a) fmt.Println("1") }(i) fmt.Println("2") time.Sleep(1 * time.Second)}Bei der Ausführung dieses Codes tritt ein Fehler auf: Schwerwiegender Fehler: Alle Goroutinen schlafen – Deadlock!
Dieser Fehler bedeutet, dass der Thread gefallen ist in einen Deadlock geraten und das Programm kann nicht weiter ausgeführt werden. Was ist also die Ursache für diesen Fehler?
ch :=make(chan int) ch <- 1 go func() { <-ch fmt.Println("1") }() fmt.Println("2")In diesem Fall In diesem Fall gibt das Programm 1, 22 aus. Fügen Sie die Codezeile ch<-1 hinter den Sub-Thread-Code ein. Der Code lautet wie folgt:
ch :=make(chan int,1) ch <- 1 go func() { v := <-ch fmt.Println(v) }() time.Sleep(1 * time.Second) fmt.Println("2")Der Haupt-Thread muss hier nicht ruhen , denn nachdem der Kanal im Hauptthread zugewiesen wurde, wird der Hauptthread blockiert, bis der Wert des Kanals im untergeordneten Thread abgerufen wird. Schauen wir uns abschließend ein Beispiel für einen Produzenten und einen Konsumenten an:
ch :=make(chan int) go func() { v := <-ch fmt.Println(v) }() ch <- 1 fmt.Println("2")Da der Kanal in diesem Code nicht gepuffert ist, blockiert der Produzenten-Thread, bis der Konsumenten-Thread annimmt, wenn der Produzent dem Kanal einen Wert zuweist die Daten aus dem Kanal aus. Nachdem der Verbraucher die Daten zum ersten Mal entnommen hat, wird der Thread des Verbrauchers auch im nächsten Zyklus blockiert, da der Produzent die Daten noch nicht gespeichert hat. Zu diesem Zeitpunkt führt das Programm den Thread des Produzenten aus. Auf diese Weise wechselt das Programm kontinuierlich zwischen den Consumer- und Producer-Threads, bis die Schleife endet. Sehen wir uns ein weiteres Beispiel mit Pufferung an:
import ( "fmt" "time")func produce(p chan<- int) { for i := 0; i < 10; i++ { p <- i fmt.Println("send:", i) } }func consumer(c <-chan int) { for i := 0; i < 10; i++ { v := <-c fmt.Println("receive:", v) } }func main() { ch := make(chan int) go produce(ch) go consumer(ch) time.Sleep(1 * time.Second) }In diesem Programm kann der Puffer 10 Ganzzahlen vom Typ int speichern, der Thread wird nicht blockiert und es werden 10 Ganzzahlen gleichzeitig gespeichert Die Ganzzahl wird im Kanal gespeichert und beim Lesen auch auf einmal gelesen.
Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung des Golang-Kanals Chan. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!