🚀 Lehrpfad 3: Concurrency & Channels

Go 10: Channels, Pufferung & Daten-Pipelines

„Do not communicate by sharing memory; instead, share memory by communicating.“ – Beherrsche gepufferte und ungepufferte Channels für typsicheren Nachrichtenaustausch.

📂 Dateien dieser Lerneinheit:
📄 aufgabe.go (Startercode) 🧪 test_aufgabe.go (Tests) 💡 musterloesung.go (Lösung) 📖 README.md

📦 1. Unbuffered vs. Buffered Channels

Channels sind typsichere Kommunikationskanäle zwischen Goroutines. Sie garantieren thread-sichere Übergaben ohne manuelle Mutex-Locks.

[Unbuffered: Synchrone Übergabe]
Sender: [ch <- val] ──(Blockiert bis Empfänger bereit)──> [val := <-ch] : Empfänger

[Buffered: Asynchrone Warteschlange, Kapazität: 3]
Sender: [ch <- val] ──> [ [Slot 1] [Slot 2] [Slot 3] ] ──> [val := <-ch] : Empfänger
                      (Blockiert erst wenn Puffer voll ist)
// 1. Unbuffered Channel (Kapazität 0): Synchroner Rendezvous-Punkt
ch := make(chan int)

// 2. Buffered Channel (Kapazität N): Asynchroner Ringpuffer
bufferedCh := make(chan string, 5)

// 3. Senden und Empfangen:
bufferedCh <- "Event 1"     // Schreibt in Puffer (nicht-blockierend solange Puffer < 5)
msg := <-bufferedCh        // Liest aus Puffer ("Event 1")

// 4. Prüfen ob Channel noch offen ist (Comma-OK Idiom):
val, ok := <-bufferedCh
if !ok {
    fmt.Println("Channel wurde geschlossen!")
}

🔄 2. Channel-Direktionen & Pipeline-Pattern

In Funktionssignaturen schränken wir Kanäle auf Send-Only (chan<- T) oder Receive-Only (<-chan T) ein. Das verhindert unbeabsichtigtes Schließen oder Lesen zur Compile-Zeit!

// Producer darf nur in den Channel schreiben und ihn schließen
func Produce(out chan<- int) {
    for i := 1; i <= 3; i++ {
        out <- i * 10
    }
    close(out) // ⚠️ WICHTIG: Nur der SENDER schließt den Channel!
}

// Consumer darf nur aus dem Channel lesen
func Consume(in <-chan int) {
    // Liest automatisch bis close(in) ausgeführt wird:
    for val := range in {
        fmt.Println("Empfangen:", val)
    }
}
🏭 Didaktische Analogie: Das Montage-Förderband

Stell dir ein Fließband in einer Fabrik vor: Goroutine 1 (Producer) legt Bauteile auf das Band. Ein ungepuffertes Band stoppt sofort, wenn am anderen Ende niemand steht, um das Teil entgegenzunehmen. Ein gepuffertes Band (Kapazität 5) kann 5 Teile zwischenlagern. Sobald die Schicht vorbei ist, schaltet der Producer die Signallampe aus (close(ch)) und der Consumer weiß, wann die Arbeit getan ist.

📑 3. Cheat-Sheet: Channel Operationen & Panics

Operation Offener Channel Geschlossener Channel (closed) Nil Channel (nil)
Senden (ch <- v) Erfolgreich (blockiert wenn voll) 💥 PANIC (send on closed channel) ⏳ Blockiert für immer
Empfangen (v := <-ch) Liefert Wert (blockiert wenn leer) Liefert Zero-Value & ok=false ⏳ Blockiert für immer
Schließen (close(ch)) Erfolgreich 💥 PANIC (close of closed channel) 💥 PANIC (close of nil channel)

🧠 Diagnostischer Selbst-Check

Überprüfe dein Verständnis der Kernkonzepte und typischen Go-Fallen, bevor du die Übung in der Web-IDE bearbeitest.

🎯 Aufgaben & Checkliste in aufgabe.go

💡 Go Pro-Tipp: Kanal-Eigentümerschaft (Channel Ownership)

Die Goroutine, die einen Channel erstellt und befüllt, ist der Owner. Nur der Owner sollte in den Channel schreiben und ihn mit close() schließen. Consumer sollten niemals fremde Channels schließen!

💻 In Web-IDE öffnen → ← Zurück zu Go 09 Weiter zu Go 11: select & Timeouts →