Goroutines drosseln
Nebenläufigkeit steuern
Goroutines drosseln ist eine kostenlose Go Academy-Lektion auf CoddyKit. Dies ist Lektion 3 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.
Parallelität begrenzen
Manchmal begrenzen Sie nicht die Anzahl pro Sekunde, sondern wie viele Goroutinen gleichzeitig ausgeführt werden. Dadurch wird die gleichzeitige Last auf eine Ressource unabhängig vom zeitlichen Ablauf begrenzt.
- Begrenzt die Parallelität
- Schützt Verbindungspools
- Verhindert Speicherspitzen
Der Semaphore-Kanal
Ein gepufferter Kanal funktioniert als Zählsemaphore. Seine Kapazität entspricht der maximalen Parallelität. Beim Belegen wird ein Token gesendet, beim Freigeben wird eines empfangen.
sem := make(chan struct{}, 3)Belegen und freigeben
Senden Sie vor dem Start der Arbeit in den Kanal, um einen Slot zu belegen (bei einem vollen Kanal wird blockiert). Empfangen Sie nach Abschluss, um den Slot freizugeben und ihn für eine andere Goroutine verfügbar zu machen.
sem <- struct{}{} // acquire
// do work
<-sem // releaseWarum struct{}
Eine leere Struktur struct{}{} belegt null Bytes. Wenn Sie sie als Kanalelement verwenden, wird die Semaphore zu einem reinen Signal ohne unnötigen Speicherverbrauch.
Eine Schleife begrenzen
Starten Sie für jede Aufgabe eine Goroutine, lassen Sie sie aber jeweils durch die Semaphore steuern. Höchstens cap Goroutinen erledigen gleichzeitig echte Arbeit; die übrigen blockieren beim Belegen.
for _, task := range tasks {
sem <- struct{}{}
go func(t Task) {
defer func() { <-sem }()
process(t)
}(t)
}Mit WaitGroup kombinieren
Die Semaphore begrenzt die Parallelität, teilt Ihnen aber nicht mit, wann alle Aufgaben abgeschlossen sind. Kombinieren Sie sie mit einer sync.WaitGroup, um auf alle Aufgaben zu warten.
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
defer func() { <-sem }()
process(t)
}()In defer freigeben
Geben Sie immer in einem defer frei, damit der Slot auch dann freigegeben wird, wenn die Arbeit eine Panic auslöst oder vorzeitig zurückkehrt. Wenn Sie die Freigabe vergessen, gehen Slots verloren und neue Beleger blockieren schließlich dauerhaft.
Ein vollständiger Lauf mit begrenzter Parallelität
Dieses Programm führt acht Aufgaben mit höchstens zwei gleichzeitig aus und gibt Start und Ende aus, um die Begrenzung in Aktion zu zeigen.
package main
import (
"fmt"
"sync"
"time"
)
func main() {
sem := make(chan struct{}, 2)
var wg sync.WaitGroup
for i := 0; i < 8; i++ {
wg.Add(1)
sem <- struct{}{}
go func(id int) {
defer wg.Done()
defer func() { <-sem }()
fmt.Println("start", id)
time.Sleep(20 * time.Millisecond)
fmt.Println("end", id)
}(i)
}
wg.Wait()
fmt.Println("done")
}errgroup mit SetLimit
Das Paket golang.org/x/sync/errgroup bietet SetLimit, um eine Gruppe zu begrenzen und den ersten Fehler weiterzugeben. Für viele Fälle ist es eine übersichtlichere Alternative, allerdings handelt es sich um ein externes Paket.
Begrenzung vs. Worker-Pool
Ein Worker-Pool verwendet eine feste Anzahl wiederverwendbarer Goroutinen, die Aufgaben aus einer Warteschlange abholen. Bei der Begrenzung durch eine Semaphore wird für jede Aufgabe eine Goroutine gestartet, aber die Anzahl aktiver Goroutinen begrenzt. Pools sind bei sehr vielen Aufgaben schlanker; Semaphoren lassen sich einfacher nachrüsten.
Das richtige Limit wählen
Setzen Sie das Limit für Datenbankaufrufe auf die Größe Ihres Verbindungspools oder darunter. Für ausgehende HTTP-Aufrufe sollte es dem Verbindungslimit des Hosts entsprechen. Ein zu hoher Wert erschöpft die Ressourcen, ein zu niedriger Wert verschwendet Kapazität.
Kurztest
Testen Sie Ihr Wissen über die Begrenzung der Parallelität.
Zusammenfassung
Sie haben gelernt, wie man Goroutinen begrenzt:
- Ein gepufferter Kanal fungiert als Zählsemaphore
- Durch Senden belegen, durch Empfangen in defer freigeben
- struct{}-Elemente belegen null Bytes
- Mit WaitGroup kombinieren, um auf den Abschluss zu warten
- Das Limit an die geschützte Ressource anpassen
Häufig gestellte Fragen
Ist die Lektion „Goroutines drosseln“ kostenlos?
Ja — der vollständige Text von „Goroutines drosseln“ 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 drosseln“?
Nebenläufigkeit steuern 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 3 von 4.
Wie lange dauert die Lektion „Goroutines drosseln“?
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.
Alle Lektionen in diesem Kurs
- Das Token-Bucket-Konzept
- golang.org/x/time/rate
- Goroutines drosseln
- Backoff und Wiederholung