- Dynamic Sidebar mit window.COURSES_MANIFEST für 13 Kurse (216 Kapitel) - Kurswechsler Dropdown mit Direktnavigation - Fortschrittsanzeige mit Solved-Checkmarks (✓) aus localStorage - Responsive Off-Canvas Drawer mit Floating Action Button (☰ Kapitel) & Backdrop auf Mobile/Tablets - Web-IDE Topbar Drawer-Button (☰ Kapitel) für unterbrechungsfreien Vollbild-Editor - Saubere Bereinigung redundanter statischer Legacy-Sidebars |
||
|---|---|---|
| .. | ||
| aufgabe.go | ||
| index.html | ||
| musterloesung.go | ||
| README.md | ||
| test_aufgabe.go | ||
Go 09: Leichtgewichtige Goroutines & sync.WaitGroup 🚀
Willkommen zu Modul 09 des Go Cloud & Concurrency Lehrpfads!
In diesem Modul lernst du, wie Gos bahnbrechendes Concurrency-Modell funktioniert, wie du Goroutines mit dem go-Schlüsselwort startest und wie du nebenläufige Workloads mit sync.WaitGroup deterministisch synchronisierst.
💡 1. Das Wichtigste in Kürze
Was macht Goroutines so mächtig?
- Geringer Footprint: Eine Goroutine benötigt anfangs nur ca. 2 KB Stack (im Vergleich zu 1–2 MB bei klassischen OS-Threads).
- Go Runtime Scheduler: Go verwendet ein M:N Multiplexing-Modell (G-P-M Modell: Goroutines werden auf logische Prozessoren und physische OS-Threads gemappt).
- Nicht-präemptiv / Kooperativ: Umschalten zwischen Goroutines passiert blitzschnell bei I/O, Channel-Operationen, Mutex-Sperren oder Funktionsaufrufen.
Das sync.WaitGroup Dreigespann
Um auf das Beenden von Hintergrund-Goroutines zu warten, verwenden wir sync.WaitGroup:
wg.Add(n): Erhöht den Zähler um die Anzahl geplanter Goroutines (immer vor demgo-Aufruf ausführen!).defer wg.Done(): Dekrementiert den Zähler beim Beenden der Goroutine.wg.Wait(): Blockiert, bis der Zähler 0 erreicht.
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(workerID int) {
defer wg.Done()
fmt.Printf("Worker %d erledigt Aufgabe\n", workerID)
}(i) // Variable als Parameter übergeben
}
wg.Wait()
fmt.Println("Alle 5 Worker sind fertig!")
⚠️ ACHTUNG:
sync.WaitGroupdarf niemals als Wertkopie an Funktionen übergeben werden, sondern immer als Pointer (*sync.WaitGroup), da sonst die interne Zählung verloren geht und ein Deadlock entsteht!
🎯 Aufgaben in aufgabe.go
- TODO 1 (
ServerMetric): Definiere das StructServerMetricmit FeldernServerID string,LatencyMs int,Status stringundTimestamp time.Time. - TODO 2 (
CheckServer): Schreibe die Worker-FunktionCheckServer(serverID string, wg *sync.WaitGroup, out chan<- ServerMetric). Nutzedefer wg.Done(). - TODO 3 (
BatchHealthCheck): Starte für eine Server-Liste parallele Goroutines mitsync.WaitGroup, sammle alle Metriken ein und gib sie sortiert nach ServerID zurück. - TODO 4 (
ParallelTaskRunner): Führe einen Slice vontasks []func() stringnebenläufig aus und sammle alle Ergebnisse exakt in der Reihenfolge ihrer Indizes ein.
🧪 Tests ausführen
Starte die Testsuite im Terminal oder in der Web-IDE:
go test -v ./...