Lancer des goroutines
Mot-clé go, cycle de vie des goroutines et WaitGroups
Lancer des goroutines est une leçon Go Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Go Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Go Academy comprend 4 leçons au total.
Qu'est-ce qu'une goroutine ?
Une goroutine est une fonction légère qui s'exécute de manière concurrente et qui est gérée par l'environnement d'exécution Go. Les goroutines coûtent beaucoup moins cher que les fils d'exécution du système d'exploitation — vous pouvez en exécuter des milliers :
- Démarrez-en une avec le mot-clé
go - Pile initiale d'environ 2 Ko (qui s'agrandit dynamiquement)
- Planifiées par l'environnement d'exécution Go, et non par le système d'exploitation
- Communiquent via des canaux, et non par la mémoire partagée
Le mot-clé go
Faites précéder tout appel de fonction de go pour le lancer comme goroutine :
package main
import ("fmt"; "time")
func greet(name string) {
fmt.Printf("Hello, %s!\n", name)
}
func main() {
go greet("Alice") // runs concurrently
go greet("Bob") // runs concurrently
time.Sleep(100 * time.Millisecond) // wait for goroutines
fmt.Println("done")
}Cycle de vie d'une goroutine
Une goroutine démarre lorsque l'instruction go est exécutée et se termine lorsque sa fonction renvoie une valeur. Si main se termine, toutes les goroutines sont arrêtées :
package main
import ("fmt"; "time")
func worker(id int) {
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Duration(id) * 50 * time.Millisecond)
fmt.Printf("Worker %d done\n", id)
}
func main() {
for i := 1; i <= 3; i++ {
go worker(i)
}
time.Sleep(300 * time.Millisecond) // naive wait
}sync.WaitGroup pour la coordination
Utilisez sync.WaitGroup plutôt que sleep pour attendre la fin des goroutines :
package main
import ("fmt"; "sync")
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // signal completion
fmt.Printf("Worker %d working\n", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1) // register one goroutine
go worker(i, &wg)
}
wg.Wait() // block until all Done()
fmt.Println("all workers finished")
}Goroutines anonymes
Lancez directement une fonction anonyme comme goroutine — c'est utile pour les tâches concurrentes écrites sur place :
package main
import ("fmt"; "sync")
func main() {
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
i := i // capture loop variable
wg.Add(1)
go func() {
defer wg.Done()
fmt.Printf("goroutine %d\n", i)
}()
}
wg.Wait()
}Piège de capture de variable de boucle
Sans capturer la variable de boucle, toutes les goroutines peuvent voir la même valeur (la valeur finale) — un problème classique de concurrence en Go :
package main
import ("fmt"; "sync")
func main() {
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(n int) { // pass i as argument — safe
defer wg.Done()
fmt.Println(n) // prints 0, 1, 2 in some order
}(i)
}
wg.Wait()
}Goroutines et fils d'exécution
Pourquoi les goroutines sont préférées aux fils d'exécution du système d'exploitation :
- Pile initiale de 2 Ko contre environ 1 Mo pour les fils d'exécution du système d'exploitation
- Création en quelques microsecondes contre quelques millisecondes
- L'environnement d'exécution Go répartit les goroutines sur les fils d'exécution du système d'exploitation définis par GOMAXPROCS
- Les changements de goroutine sont coopératifs — le noyau n'intervient pas
- Go gère la planification ; vous vous concentrez sur la logique
GOMAXPROCS
runtime.GOMAXPROCS contrôle le nombre de fils d'exécution du système d'exploitation qui exécutent des goroutines en parallèle (par défaut, il correspond au nombre de processeurs) :
package main
import ("fmt"; "runtime")
func main() {
// Default: number of available CPU cores
fmt.Println("CPUs:", runtime.NumCPU())
fmt.Println("GOMAXPROCS:", runtime.GOMAXPROCS(0)) // 0 = query without changing
// Set to 1 for debugging race conditions:
// runtime.GOMAXPROCS(1)
fmt.Println("Goroutines:", runtime.NumGoroutine())
}Fuites de goroutines
Une fuite de goroutine se produit lorsqu'une goroutine est démarrée mais ne se termine jamais. Causes courantes : réception bloquée sur un canal, mutex bloqué ou absence d'annulation :
package main
import ("fmt"; "time"; "runtime")
func leaky() {
ch := make(chan int) // nobody sends to ch
go func() {
v := <-ch // blocks forever — goroutine leaked!
fmt.Println(v)
}()
}
func main() {
leaky()
time.Sleep(10 * time.Millisecond)
fmt.Println("goroutines:", runtime.NumGoroutine()) // > 1
}Bonnes pratiques pour les goroutines
Recommandations concernant les goroutines :
- Sachez toujours comment une goroutine va se terminer
- Utilisez WaitGroup ou des canaux pour synchroniser, et non sleep
- Transmettez les variables de boucle comme arguments de fonction, et non via une fermeture
- Annulez les goroutines avec context ; ne les laissez pas s'exécuter indéfiniment
- Utilisez le détecteur de conditions de concurrence :
go run -race main.go
Vérification rapide
Quelle est la bonne manière d'éviter le problème de capture de variable de boucle dans les goroutines ?
Récapitulatif : lancement de goroutines
Résumé :
- Lancez-les avec
go fn()— légères et peu coûteuses - Utilisez
sync.WaitGrouppour attendre :Add(1),defer Done(),Wait() - Capturez les variables de boucle comme arguments ou en les redéclarant
- Sachez toujours comment chaque goroutine se termine — évitez les fuites
- Utilisez l'option
-racepour détecter les accès concurrents aux données
Questions Fréquemment Posées
La leçon « Lancer des goroutines » est-elle gratuite ?
Oui — le texte complet de « Lancer des goroutines » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Go Academy, passe à CoddyKit PRO. Le cours Go Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Lancer des goroutines » ?
Mot-clé go, cycle de vie des goroutines et WaitGroups Tu pratiques Go Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Go Academy ?
Aucune expérience préalable n'est requise. Go Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.
Combien de temps prend la leçon « Lancer des goroutines » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Go Academy ?
Oui. Chaque leçon Go Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Lancer des goroutines
- Canaux non tamponnés
- Canaux tamponnés
- Direction des canaux et modèles de pipeline