capypad
0 Tage Serie
go / beginner
Snippet

Kanal-Kommunikation mit Select

Die select-Anweisung ermöglicht es einer Goroutine, auf mehrere Kanal-Operationen gleichzeitig zu warten. Sie blockiert, bis einer ihrer Fälle fortfahren kann, dann wird dieser Fall ausgeführt. Wenn mehrere Fälle bereit sind, wählt select zufällig. Dies ist Go's Art, asynchrone Kommunikation zwischen Goroutinen zu handhaben. Das select mit einem default-Fall ist nicht-blockierend - es prüft alle Fälle ohne zu warten.

snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main
 
import (
"fmt"
"time"
)
 
func worker(id int, ch chan string, done chan bool) {
for i := 0; i < 3; i++ {
select {
case msg := <-ch:
fmt.Printf("Worker %d received: %s\n", id, msg)
case <-time.After(time.Millisecond * 100):
fmt.Printf("Worker %d timed out\n", id)
}
}
done <- true
}
 
func main() {
ch1 := make(chan string, 1)
ch2 := make(chan string, 1)
done := make(chan bool)
 
go worker(1, ch1, done)
go worker(2, ch2, done)
 
ch1 <- "Hello from main"
ch2 <- "Greetings from main"
 
time.Sleep(time.Millisecond * 50)
ch1 <- "Another message to worker 1"
 
<-done
<-done
fmt.Println("All workers finished")
}
Erklärung
1
select { case msg := <-ch: }
Warte auf einen Wert, der auf ch gesendet wird, dann weise ihn msg zu und führe den Fall aus
2
case <-time.After(time.Millisecond * 100)
Eingebauter Timeout-Fall - empfängt von einem Kanal, der nach der Dauer sendet
3
ch1 := make(chan string, 1)
Pufferkanal mit Kapazität 1 - Sender blockiert nicht, bis Puffer voll ist
4
go worker(1, ch1, done)
Startet Worker-Goroutine - läuft gleichzeitig mit der main-Funktion