Goroutines starten
Das Schlüsselwort go, der Lebenszyklus von Goroutines und WaitGroups
Goroutines starten ist eine kostenlose Go Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Go Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Go Academy-Kurs umfasst insgesamt 4 Lektionen.
Was ist eine Goroutine?
Eine Goroutine ist eine leichtgewichtige, nebenläufig ausgeführte Funktion, die von der Go-Laufzeitumgebung verwaltet wird. Goroutines sind wesentlich kostengünstiger als Betriebssystem-Threads — Sie können Tausende davon ausführen:
- Start mit dem Schlüsselwort
go - Anfangs-Stack ~2 KB (wächst dynamisch)
- Von der Go-Laufzeitumgebung eingeplant, nicht vom Betriebssystem
- Kommunikation über Channels statt über gemeinsam genutzten Speicher
Das Schlüsselwort go
Stellen Sie jedem Funktionsaufruf go voran, um ihn als Goroutine zu starten:
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")
}Lebenszyklus einer Goroutine
Eine Goroutine startet, sobald die Anweisung go ausgeführt wird, und endet, wenn ihre Funktion zurückkehrt. Wenn main zurückkehrt, werden alle Goroutines beendet:
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 zur Koordination
Verwenden Sie sync.WaitGroup anstelle von sleep, um auf das Ende von Goroutines zu warten:
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")
}Anonyme Goroutines
Starten Sie eine anonyme Funktion direkt als Goroutine — nützlich für nebenläufige Aufgaben direkt an der Aufrufstelle:
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()
}Tücken beim Erfassen von Schleifenvariablen
Wenn Sie die Schleifenvariable nicht erfassen, sehen möglicherweise alle Goroutines denselben (letzten) Wert — ein klassischer Go-Nebenläufigkeitsfehler:
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 vs. Threads
Warum Goroutines gegenüber Betriebssystem-Threads bevorzugt werden:
- 2 KB Anfangs-Stack gegenüber ~1 MB bei Betriebssystem-Threads
- Erstellung dauert Mikrosekunden statt Millisekunden
- Die Go-Laufzeitumgebung verteilt Goroutines auf GOMAXPROCS Betriebssystem-Threads
- Der Wechsel zwischen Goroutines erfolgt kooperativ — ohne Beteiligung des Kernels
- Go übernimmt die Planung, Sie konzentrieren sich auf die Logik
GOMAXPROCS
runtime.GOMAXPROCS steuert, wie viele Betriebssystem-Threads Goroutines parallel ausführen (standardmäßig entspricht der Wert der Anzahl der CPUs):
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())
}Goroutine-Leaks
Ein Goroutine-Leak tritt auf, wenn eine Goroutine gestartet wird, aber nie endet. Häufige Ursachen sind ein blockierter Channel-Empfang, ein blockierter Mutex oder fehlende Abbruchmöglichkeiten:
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
}Bewährte Vorgehensweisen für Goroutines
Richtlinien für Goroutines:
- Stellen Sie immer sicher, wie eine Goroutine beendet wird
- Verwenden Sie zur Synchronisierung eine WaitGroup oder Channels, nicht sleep
- Übergeben Sie Schleifenvariablen als Funktionsargumente statt über eine Closure
- Brechen Sie Goroutines mit einem Context ab, anstatt sie weiterlaufen zu lassen
- Verwenden Sie den Race Detector:
go run -race main.go
Kurztest
Wie vermeiden Sie den Fehler durch das Erfassen der Schleifenvariable in Goroutines korrekt?
Zusammenfassung: Goroutines starten
Zusammenfassung:
- Start mit
go fn()— leichtgewichtig und kostengünstig - Verwenden Sie
sync.WaitGroupzum Warten:Add(1),defer Done(),Wait() - Erfassen Sie Schleifenvariablen als Argument oder durch erneute Deklaration
- Stellen Sie immer sicher, wie jede Goroutine endet — so verhindern Sie Leaks
- Verwenden Sie das
-race-Flag, um Datenrennen zu erkennen
Häufig gestellte Fragen
Ist die Lektion „Goroutines starten“ kostenlos?
Ja — der vollständige Text von „Goroutines starten“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Go Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Go Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Goroutines starten“?
Das Schlüsselwort go, der Lebenszyklus von Goroutines und WaitGroups Du übst Go Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Go Academy zu starten?
Keine Vorkenntnisse erforderlich. Go Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „Goroutines starten“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Go Academy-Lektion Code schreiben und ausführen?
Ja. Jede Go Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.