go / expert
Snippet
Priorisiertes Kanal-Auswahlmuster für Pipelines mit hohem Durchsatz
Standard-select-Blöcke in Go werten bereitstehende Fälle pseudo-zufällig aus, um Starvation zu vermeiden. Um eine deterministische Prioritätssteuerung aufzubauen, muss ein nicht-blockierender select-Block mit default-Klausel zuerst die hochpriorisierten Kanäle abfragen, bevor auf ein blockierendes select zurückgegriffen wird.
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
38
39
40
41
42
43
44
45
package mainimport ("context""fmt""time")func PrioritySelect(ctx context.Context, highPri <-chan int, lowPri <-chan int) {for {select {case <-ctx.Done():fmt.Println("Shutting down priority consumer")returncase item := <-highPri:fmt.Println("High priority item processed:", item)continuedefault:}select {case <-ctx.Done():fmt.Println("Shutting down priority consumer")returncase item := <-highPri:fmt.Println("High priority item processed:", item)case item := <-lowPri:fmt.Println("Low priority item processed:", item)}}}func main() {ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)defer cancel()high := make(chan int, 10)low := make(chan int, 10)high <- 100low <- 1high <- 200PrioritySelect(ctx, high, low)}
Erklärung
1
select { case item := <-highPri: ... default: }
Führt zuerst eine nicht-blockierende Prüfung auf dem Hochprioritätskanal aus; falls eine Nachricht vorliegt, wird diese direkt verarbeitet.
2
select { case <-ctx.Done(): ... case item := <-highPri: ... case item := <-lowPri: ... }
Blockierendes Fallback-select, das die Ausführung anhält, bis Daten auf einem Kanal eintreffen oder der Kontext beendet ist.