Ungepufferte Channels
Synchrones Übergeben zwischen Goroutines
Ungepufferte Channels ist eine kostenlose Go Academy-Lektion auf CoddyKit. Dies ist Lektion 2 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 ein Channel?
Ein Channel ist ein typisierter Kommunikationsweg zwischen Goroutines. Channels folgen dem Leitgedanken von Go: Kommunizieren Sie nicht, indem Sie Speicher gemeinsam nutzen; nutzen Sie Speicher gemeinsam, indem Sie kommunizieren.
package main
import "fmt"
func main() {
ch := make(chan int) // unbuffered int channel
go func() {
ch <- 42 // send: blocks until someone receives
}()
v := <-ch // receive: blocks until someone sends
fmt.Println(v) // 42
}Verhalten ungepufferter Channels
Ein ungepufferter Channel hat keine Kapazität. Ein Sendevorgang blockiert, bis ein Empfänger bereit ist, und ein Empfang blockiert, bis ein Sender sendet. Dadurch wird eine garantierte synchrone Übergabe ermöglicht:
package main
import "fmt"
func double(in <-chan int, out chan<- int) {
for v := range in {
out <- v * 2
}
close(out)
}
func main() {
in := make(chan int)
out := make(chan int)
go double(in, out)
go func() { in <- 3; in <- 5; close(in) }()
for v := range out { fmt.Println(v) }
// 6
// 10
}Channel zur Synchronisierung
Ungepufferte Channels synchronisieren Goroutines — verwenden Sie sie als Signal dafür, dass die Arbeit abgeschlossen ist:
package main
import "fmt"
func compute(result chan<- int) {
sum := 0
for i := 1; i <= 100; i++ { sum += i }
result <- sum
}
func main() {
ch := make(chan int)
go compute(ch)
fmt.Println("Result:", <-ch) // blocks until compute sends
}Einen Channel schließen
Der Sender schließt einen Channel mit close(ch), um zu signalisieren, dass keine weiteren Werte gesendet werden. Empfänger erkennen das Schließen über die Form mit zwei Werten:
package main
import "fmt"
func generate(ch chan<- int, max int) {
for i := 0; i < max; i++ {
ch <- i
}
close(ch) // signal done
}
func main() {
ch := make(chan int)
go generate(ch, 5)
for v := range ch { // range detects close automatically
fmt.Println(v)
}
fmt.Println("channel closed")
}Empfang mit zwei Werten
Der Empfang mit zwei Werten v, ok := <-ch zeigt an, ob der Channel noch geöffnet ist:
package main
import "fmt"
func main() {
ch := make(chan string, 1)
ch <- "hello"
close(ch)
v1, ok1 := <-ch
fmt.Println(v1, ok1) // hello true
v2, ok2 := <-ch
fmt.Println(v2, ok2) // "" false — channel closed
}Senden auf einem geschlossenen Channel führt zu einem Panic
Das Senden an einen geschlossenen Channel löst einen Panic aus. Nur der Sender sollte einen Channel schließen — niemals der Empfänger:
package main
import "fmt"
func main() {
ch := make(chan int)
close(ch)
// Receiving from closed channel returns zero value
v, ok := <-ch
fmt.Println(v, ok) // 0 false
// Sending to closed channel panics:
defer func() { recover() }()
ch <- 1 // panic: send on closed channel
}Gerichtete Channels
Beschränken Sie Channels in Funktionssignaturen aus Gründen der Klarheit und Sicherheit auf das Senden (chan<- T) oder den Empfang (<-chan T):
package main
import "fmt"
func producer(out chan<- int) { // send-only
for i := 0; i < 3; i++ { out <- i }
close(out)
}
func consumer(in <-chan int) { // receive-only
for v := range in { fmt.Println(v) }
}
func main() {
ch := make(chan int)
go producer(ch)
consumer(ch)
}Goroutine-Channel-Ping-Pong
Zwei Goroutines übergeben sich über Channels abwechselnd eine Nachricht — ein klassisches Beispiel für Synchronisierung:
package main
import "fmt"
func ping(ping, pong chan struct{}) {
for i := 0; i < 3; i++ {
<-ping
fmt.Println("ping")
pong <- struct{}{}
}
}
func main() {
ping := make(chan struct{})
pong := make(chan struct{})
go func() { for { <-pong; fmt.Println("pong"); ping <- struct{}{} } }()
go func() { for i := 0; i < 3; i++ { ping <- struct{}{}; <-pong } }()
// Simplified version:
fmt.Println("channels enable structured communication")
}Nil-Channels blockieren für immer
Das Empfangen von einem oder Senden an einen nil-Channel blockiert für immer. Dies wird manchmal absichtlich in select-Anweisungen verwendet:
package main
import "fmt"
func main() {
var ch chan int // nil channel
fmt.Println(ch == nil) // true
// select with nil channel — that case is never selected
active := make(chan int, 1)
active <- 42
select {
case v := <-ch: // never selected (nil)
fmt.Println(v)
case v := <-active: // selected
fmt.Println("got:", v)
}
}Wann ungepufferte Channels verwendet werden
Verwenden Sie ungepufferte Channels, wenn:
- Sie eine garantierte synchrone Übergabe benötigen
- Die Goroutine den Empfang bestätigen muss, bevor der Sender fortfährt
- Sie Semaphoren oder Backpressure implementieren
- Sie Pipelines implementieren, in denen jede Stufe jeweils ein Element verarbeiten soll
Kurztest
Was geschieht, wenn Sie auf einem ungepufferten Channel senden, für den kein Empfänger bereit ist?
Zusammenfassung: Ungepufferte Channels
Zusammenfassung:
- Erstellen Sie sie mit
make(chan T)— ohne Kapazität - Senden blockiert, bis ein Empfänger bereit ist; Empfangen blockiert, bis ein Sender sendet
- Nur der Sender sollte einen Channel schließen
range chiteriert, bis der Channel geschlossen wird- Empfang mit zwei Werten:
v, ok := <-ch - Verwenden Sie gerichtete Typen für mehr Klarheit:
chan<-und<-chan
Häufig gestellte Fragen
Ist die Lektion „Ungepufferte Channels“ kostenlos?
Ja — der vollständige Text von „Ungepufferte Channels“ 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 „Ungepufferte Channels“?
Synchrones Übergeben zwischen Goroutines 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 2 von 4.
Wie lange dauert die Lektion „Ungepufferte Channels“?
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
- Goroutines starten
- Ungepufferte Channels
- Gepufferte Channels
- Channel-Richtung und Pipeline-Patterns