Heim Backend-Entwicklung Golang Parallelität in Go: Von den Grundlagen zu fortgeschrittenen Konzepten

Parallelität in Go: Von den Grundlagen zu fortgeschrittenen Konzepten

Oct 03, 2024 am 06:11 AM

Concurrency in Go: From Basics to Advanced Concepts

Table of Contents

  1. Introduction to Concurrency
  2. Concurrency vs Parallelism
  3. Go-routines: The Building Blocks of Concurrency
  4. Channels: Communication Between Go-routines
  5. Select Statement: Managing Multiple Channels
  6. Synchronization Primitives
  7. Concurrency Patterns
  8. Context Package: Managing Cancellation and Timeouts.
  9. 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()
Nach dem Login kopieren

Or with an anonymous function:

go func() {
    // function body
}()
Nach dem Login kopieren

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")
}
Nach dem Login kopieren

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")
}
Nach dem Login kopieren

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
Nach dem Login kopieren

Sending: Values are sent to a channel using the <- operator:

ch <- 42  // Send the value 42 to the channel
Nach dem Login kopieren

Receiving: Values are received from a channel using the <- operator:

value := <-ch  // Receive a value from the channel
Nach dem Login kopieren

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
Nach dem Login kopieren

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
Nach dem Login kopieren

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)
}
Nach dem Login kopieren

Closing Channels

Channels can be closed to signal that no more values will be sent:

close(ch)
Nach dem Login kopieren

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")
}
Nach dem Login kopieren

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)
}
Nach dem Login kopieren

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!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
2 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Repo: Wie man Teamkollegen wiederbelebt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Abenteuer: Wie man riesige Samen bekommt
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

GO Language Pack Import: Was ist der Unterschied zwischen Unterstrich und ohne Unterstrich? GO Language Pack Import: Was ist der Unterschied zwischen Unterstrich und ohne Unterstrich? Mar 03, 2025 pm 05:17 PM

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 kann ich kurzfristige Informationsübertragung zwischen Seiten im BeEGO-Framework implementieren? Mar 03, 2025 pm 05:22 PM

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 konvertieren Sie die Liste der MySQL -Abfrageergebnisse in eine benutzerdefinierte Struktur -Slice in Go -Sprache? Mar 03, 2025 pm 05:18 PM

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 kann ich benutzerdefinierte Typ -Einschränkungen für Generika in Go definieren? Mar 10, 2025 pm 03:20 PM

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 Scheinobjekte und Stubs zum Testen in Go? Mar 10, 2025 pm 05:38 PM

Wie schreibe ich Scheinobjekte und Stubs zum Testen in Go?

Wie schreibe ich Dateien in Go Language bequem? Wie schreibe ich Dateien in Go Language bequem? Mar 03, 2025 pm 05:15 PM

Wie schreibe ich Dateien in Go Language bequem?

Wie schreibt man Unit -Tests in Go? Wie schreibt man Unit -Tests in Go? Mar 21, 2025 pm 06:34 PM

Wie schreibt man Unit -Tests in Go?

Wie kann ich Tracing -Tools verwenden, um den Ausführungsfluss meiner GO -Anwendungen zu verstehen? Wie kann ich Tracing -Tools verwenden, um den Ausführungsfluss meiner GO -Anwendungen zu verstehen? Mar 10, 2025 pm 05:36 PM

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

See all articles