Inhaltsverzeichnis
1.Einführung in die Parallelität
Parallelität ist die Fähigkeit, mehrere Aufgaben gleichzeitig zu bearbeiten. In Go ist Parallelität ein erstklassiger Bürger, der in das Kerndesign der Sprache integriert ist. Gos Ansatz zur Parallelität basiert auf Communicating Sequential Processes (CSP), einem Modell, das die Kommunikation zwischen Prozessen und nicht den gemeinsamen Speicher betont.
2.Parallelität vs. Parallelität:
Go-Routinen ermöglichen Parallelität, also die Zusammensetzung unabhängig ausgeführter Prozesse.
Parallelität (gleichzeitige Ausführung) kann auftreten, wenn das System über mehrere CPU-Kerne verfügt und die Go-Laufzeit die parallele Ausführung von Go-Routinen plant.
3. Go-Routinen:
Die Bausteine der Parallelität sind Go-Routinen sind leichtgewichtige Threads, die von der Go-Laufzeit verwaltet werden. Es handelt sich um eine Funktion oder Methode, die gleichzeitig mit anderen Funktionen oder Methoden ausgeführt wird. Go-Routinen sind die Grundlage des Parallelitätsmodells von Go.
Hauptmerkmale:
Eine Go-Routine erstellen:
Um eine Go-Routine zu starten, verwenden Sie einfach das Schlüsselwort go gefolgt von einem Funktionsaufruf:
go functionName()
Oder mit einer anonymen Funktion:
go func() { // function body }()
Go-Routine-Planung:
Kommunikation und Synchronisierung:
Beispiel mit Erklärung:
package main import ( "fmt" "time" ) func printNumbers() { for i := 1; i <= 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Printf("%d ", i) } } func printLetters() { for i := 'a'; i <= 'e'; i++ { time.Sleep(150 * time.Millisecond) fmt.Printf("%c ", i) } } func main() { go printNumbers() go printLetters() time.Sleep(2 * time.Second) fmt.Println("\nMain function finished") }
Erklärung:
Goroutine-Lebenszyklus:
Best Practices:
Einfaches Beispiel mit Erklärungen zu Go-Routinen
package main import ( "fmt" "time" ) // printNumbers is a function that prints numbers from 1 to 5 // It will be run as a goroutine func printNumbers() { for i := 1; i <= 5; i++ { time.Sleep(500 * time.Millisecond) // Sleep for 500ms to simulate work fmt.Printf("%d ", i) } } // printLetters is a function that prints letters from 'a' to 'e' // It will also be run as a goroutine func printLetters() { for i := 'a'; i <= 'e'; i++ { time.Sleep(300 * time.Millisecond) // Sleep for 300ms to simulate work fmt.Printf("%c ", i) } } func main() { // Start printNumbers as a goroutine // The 'go' keyword before the function call creates a new goroutine go printNumbers() // Start printLetters as another goroutine go printLetters() // Sleep for 3 seconds to allow goroutines to finish // This is a simple way to wait, but not ideal for production code time.Sleep(3 * time.Second) // Print a newline for better formatting fmt.Println("\nMain function finished") }
4.Kanäle:
Kanäle sind eine Kernfunktion in Go, die es Go-Routinen ermöglicht, miteinander zu kommunizieren und ihre Ausführung zu synchronisieren. Sie bieten einer Go-Routine die Möglichkeit, Daten an eine andere Go-Routine zu senden.
Zweck der Kanäle
Kanäle in Go dienen zwei Hauptzwecken:
a) Kommunikation: Sie ermöglichen Goroutinen, Werte untereinander zu senden und voneinander zu empfangen.
b) Synchronisierung: Sie können verwendet werden, um die Ausführung über Goroutinen hinweg zu synchronisieren.
Erstellung: Kanäle werden mit der Make-Funktion erstellt:
ch := make(chan int) // Unbuffered channel of integers
Senden: Werte werden mit dem <- Operator an einen Kanal gesendet:
ch <- 42 // Send the value 42 to the channel
Receiving: Values are received from a channel using the <- operator:
value := <-ch // Receive a value from the channel
Types of Channels
a) Unbuffered Channels:
ch := make(chan int) go func() { ch <- 42 // This will block until the value is received }() value := <-ch // This will receive the value
b) Buffered Channels:
ch := make(chan int, 2) ch <- 1 // Doesn't block ch <- 2 // Doesn't block ch <- 3 // This will block until a value is received
Channel Directions
Channels can be directional or bidirectional:
Example :
func send(ch chan<- int) { ch <- 42 } func receive(ch <-chan int) { value := <-ch fmt.Println(value) }
Closing Channels
Channels can be closed to signal that no more values will be sent:
close(ch)
Receiving from a closed channel:
If the channel is empty, it returns the zero value of the channel's type.
You can check if a channel is closed using a two-value receive:
value, ok := <-ch if !ok { fmt.Println("Channel is closed") }
Ranging over Channels
You can use a for range loop to receive values from a channel until it's closed:
for value := range ch { fmt.Println(value) }
Hey, Thank you for staying until the end! I appreciate you being valuable reader and learner. Please follow me here and also on my Linkedin and GitHub .
以上是Go 中的并发:从基础知识到高级概念的详细内容。更多信息请关注PHP中文网其他相关文章!