


Parallelität in Go: Von den Grundlagen zu fortgeschrittenen Konzepten
Table of Contents
- Introduction to Concurrency
- Concurrency vs Parallelism
- Go-routines: The Building Blocks of Concurrency
- Channels: Communication Between Go-routines
- Select Statement: Managing Multiple Channels
- Synchronization Primitives
- Concurrency Patterns
- Context Package: Managing Cancellation and Timeouts.
- Best Practices and Common Pitfalls**
1.Introduction to Concurrency
Concurrency is the ability to handle multiple tasks simultaneously. In Go, concurrency is a first-class citizen, built into the language's core design. Go's approach to concurrency is based on Communicating Sequential Processes (CSP), a model that emphasizes communication between processes rather than shared memory.
2.Concurrency vs Parallelism:
Go-routines enable concurrency, which is the composition of independently executing processes.
Parallelism (simultaneous execution) may occur if the system has multiple CPU cores and the Go runtime schedules go-routines to run in parallel.
3. Go-routines:
The Building Blocks of Concurrency is Go-routines are lightweight threads managed by the Go runtime. It's a function or method that runs concurrently with other functions or methods. Go-routines are the foundation of Go's concurrency model.
Key Characteristics:
- Lightweight: Go-routines are much lighter than OS threads. You can easily create thousands of go-routines without significant performance impact.
- Managed by Go runtime: The Go scheduler handles the distribution of go-routines across available OS threads.
- Cheap creation: Starting a go-routine is as simple as using the go keyword before a function call.
- Stack size: Go-routines start with a small stack (around 2KB) that can grow and shrink as needed.
Creating a Go-routine:
To start a go-routine, you simply use the go keyword followed by a function call:
go functionName()
Or with an anonymous function:
go func() { // function body }()
Go-routine Scheduling:
- The Go runtime uses a M:N scheduler, where M go-routines are scheduled onto N OS threads.
- This scheduler is non-preemptive, meaning go-routines yield control when they are idle or logically blocked.
Communication and Synchronization:
- Goroutines typically communicate using channels, adhering to the "Don't communicate by sharing memory; share memory by communicating" principle.
- For simple synchronization, you can use primitives like sync.WaitGroup or sync.Mutex.
Example with Explanation:
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") }
Explanation:
- We define two functions: printNumbers and printLetters.
- In main, we start these functions as goroutines using the go keyword.
- The main function then sleeps for 2 seconds to allow the goroutines to complete.
- Without goroutines, these functions would run sequentially. With goroutines, they run concurrently.
- The output will show numbers and letters interleaved, demonstrating concurrent execution.
Goroutine Lifecycle:
- A goroutine starts when created with the go keyword.
- It terminates when its function completes or when the program exits.
- Goroutines can be leaked if not properly managed, so it's important to ensure they can exit.
Best Practices:
- Don't create goroutines in libraries; let the caller control concurrency.
- Be cautious about creating an unbounded number of goroutines.
- Use channels or sync primitives to coordinate between goroutines.
- Consider using worker pools for managing multiple goroutines efficiently.
Simple example with explanations of go-routines
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.Channels :
Channels are a core feature in Go that allow go-routines to communicate with each other and synchronize their execution. They provide a way for one go-routine to send data to another go-routine.
Purpose of Channels
Channels in Go serve two main purposes:
a) Communication: They allow goroutines to send and receive values to and from each other.
b) Synchronization: They can be used to synchronize execution across goroutines.
Creation: Channels are created using the make function:
ch := make(chan int) // Unbuffered channel of integers
Sending: Values are sent to a channel using the <- operator:
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:
- Created without a capacity: ch := make(chan int)
- Sending blocks until another goroutine receives.
- Receiving blocks until another goroutine sends.
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:
- Created with a capacity: ch := make(chan int, 3)
- Sending only blocks when the buffer is full.
- Receiving only blocks when the buffer is empty.
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:
- Bidirectional: chan T
- Send-only: chan<- T
- Receive-only: <-chan T
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 .
Das obige ist der detaillierte Inhalt vonParallelität in Go: Von den Grundlagen zu fortgeschrittenen Konzepten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

GO Language Pack Import: Was ist der Unterschied zwischen Unterstrich und ohne Unterstrich?

Wie kann ich kurzfristige Informationsübertragung zwischen Seiten im BeEGO-Framework implementieren?

Wie konvertieren Sie die Liste der MySQL -Abfrageergebnisse in eine benutzerdefinierte Struktur -Slice in Go -Sprache?

Wie kann ich benutzerdefinierte Typ -Einschränkungen für Generika in Go definieren?

Wie schreibe ich Scheinobjekte und Stubs zum Testen in Go?

Wie schreibe ich Dateien in Go Language bequem?

Wie kann ich Tracing -Tools verwenden, um den Ausführungsfluss meiner GO -Anwendungen zu verstehen?
