Prioritizing Channel Operations with `select` Statement
Owner: SnippetBot
Created: 2026-07-24 00:00:46
Size: 1.77 KB
Expires: Never
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package main
import (
"fmt"
"time"
)
// worker simulates a task that sometimes needs to respond to urgent control signals.
func worker(dataCh <-chan string, controlCh <-chan string, done chan<- bool) {
for {
select {
case msg := <-controlCh: // Priority 1: Always check control signals first
fmt.Printf("Worker: !!! URGENT Control received: %s !!!
", msg)
if msg == "stop" {
fmt.Println("Worker: Stopping due to control signal.")
done <- true
return
}
case data := <-dataCh: // Priority 2: Process data if no control signal
fmt.Printf("Worker: Processing data: %s
", data)
time.Sleep(50 * time.Millisecond) // Simulate work
case <-time.After(200 * time.Millisecond): // Priority 3: Do something if no messages for a while
fmt.Println("Worker: Idle, performing routine check...")
}
}
}
func main() {
dataChannel := make(chan string)
controlChannel := make(chan string)
doneChannel := make(chan bool)
go worker(dataChannel, controlChannel, doneChannel)
// Send some data
go func() {
for i := 0; i < 5; i++ {
dataChannel <- fmt.Sprintf("DataItem-%d", i+1)
time.Sleep(70 * time.Millisecond)
}
}()
// Send an urgent control signal later
go func() {
time.Sleep(300 * time.Millisecond)
controlChannel <- "pause"
time.Sleep(200 * time.Millisecond)
controlChannel <- "status_report"
time.Sleep(400 * time.Millisecond)
controlChannel <- "stop" // This should cause the worker to exit
}()
// Wait for the worker to signal completion
<-doneChannel
fmt.Println("Main: Worker has completed its task.")
close(dataChannel)
close(controlChannel)
close(doneChannel) // Not strictly necessary after receive, but good practice
time.Sleep(50 * time.Millisecond) // Give time for goroutines to clean up
fmt.Println("Main: Application finished.")
}