Maison >développement back-end >Golang >Concurrence dans Go : des bases aux concepts avancés
Table des matières
1.Introduction à la concurrence
La concurrence est la capacité de gérer plusieurs tâches simultanément. Dans Go, la concurrence est un citoyen de premier ordre, intégré à la conception de base du langage. L'approche de Go en matière de concurrence est basée sur les processus séquentiels communicants (CSP), un modèle qui met l'accent sur la communication entre les processus plutôt que sur la mémoire partagée.
2.Concurrence vs Parallélisme :
Les Go-routines activent la concurrence, qui est la composition de processus s'exécutant indépendamment.
Le parallélisme (exécution simultanée) peut se produire si le système dispose de plusieurs cœurs de processeur et que le runtime Go planifie les go-routines pour qu'elles s'exécutent en parallèle.
3. Go-routines :
Les éléments constitutifs de la concurrence sont que les routines Go sont des threads légers gérés par le runtime Go. C'est une fonction ou une méthode qui s'exécute simultanément avec d'autres fonctions ou méthodes. Les routines Go sont le fondement du modèle de concurrence de Go.
Caractéristiques clés :
Créer une routine Go :
Pour démarrer une go-routine, vous utilisez simplement le mot-clé go suivi d'un appel de fonction :
go functionName()
Ou avec une fonction anonyme :
go func() { // function body }()
Planification des routines :
Communication et synchronisation :
Exemple avec explication :
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") }
Explication :
Cycle de vie des goroutines :
Bonnes pratiques :
Exemple simple avec explications des 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.Canaux :
Les canaux sont une fonctionnalité essentielle de Go qui permettent aux go-routines de communiquer entre elles et de synchroniser leur exécution. Ils permettent à une routine go d'envoyer des données à une autre routine go.
Objectif des chaînes
Les chaînes dans Go ont deux objectifs principaux :
a) Communication : ils permettent aux goroutines d'envoyer et de recevoir des valeurs entre elles.
b) Synchronisation : ils peuvent être utilisés pour synchroniser l'exécution entre les goroutines.
Création : Les chaînes sont créées à l'aide de la fonction make :
ch := make(chan int) // Unbuffered channel of integers
Envoi : les valeurs sont envoyées à un canal à l'aide de l'opérateur <- :
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 .
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!