-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.go
208 lines (163 loc) · 5.64 KB
/
main.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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package main
import (
"fmt"
"math/rand"
"time"
)
func worker(id int, ch chan<- string) {
time.Sleep(time.Duration(id) * time.Second)
ch <- fmt.Sprintf("Worker %d finished", id)
}
func main() {
fmt.Println("-----------------------------------------------------------------------------------")
// Basic Channel Select
// Demonstrates a basic use of select with multiple channels, where select waits for either of the channels to receive data
ch1 := make(chan string)
ch2 := make(chan string)
// Goroutine to send data to ch1 after 2 seconds
go func() {
time.Sleep(2 * time.Second)
ch1 <- "message from ch1"
}()
// Goroutine to send data to ch2 after 1 second
go func() {
time.Sleep(1 * time.Second)
ch2 <- "message from ch2"
}()
// Using select to wait for either ch1 or ch2 to receive data
select {
case msg1 := <-ch1:
fmt.Println("Received:", msg1)
case msg2 := <-ch2:
fmt.Println("Received:", msg2)
}
fmt.Println("-----------------------------------------------------------------------------------")
fmt.Println("-----------------------------------------------------------------------------------")
// Channel Select with Timeout
// Use the select statement to implement a timeout by using Go's time.After function.
// This example shows how to wait for a message with a timeout
ch := make(chan string)
// Goroutine to send data after a delay
go func() {
time.Sleep(3 * time.Second)
ch <- "result"
}()
// Using select to wait for either a message or a timeout
select {
case res := <-ch:
fmt.Println("Received:", res)
case <-time.After(2 * time.Second):
fmt.Println("Timeout: No response received")
}
fmt.Println("-----------------------------------------------------------------------------------")
fmt.Println("-----------------------------------------------------------------------------------")
// Channel Select with Multiple Cases and Default
// The select statement can include a default case, which is executed if none of the other cases are ready. This is useful for non-blocking channel operations
ch1 = make(chan string)
ch2 = make(chan string)
// Goroutine to send data to ch1
go func() {
time.Sleep(2 * time.Second)
ch1 <- "message from ch1"
}()
// Using select with a default case
select {
case msg1 := <-ch1:
fmt.Println("Received:", msg1)
case msg2 := <-ch2:
fmt.Println("Received:", msg2)
default:
fmt.Println("No message received, doing other work...")
}
fmt.Println("-----------------------------------------------------------------------------------")
fmt.Println("-----------------------------------------------------------------------------------")
// Channel Select with a Loop
// The select statement can be used inside a loop to continuously wait for and handle multiple channel operations
ch1 = make(chan string)
ch2 = make(chan string)
// Goroutine to send data to ch1
go func() {
time.Sleep(2 * time.Second)
ch1 <- "message from ch1"
}()
// Goroutine to send data to ch2
go func() {
time.Sleep(1 * time.Second)
ch2 <- "message from ch2"
}()
// Looping with select to handle both channels
for i := 0; i < 2; i++ {
select {
case msg1 := <-ch1:
fmt.Println("Received:", msg1)
case msg2 := <-ch2:
fmt.Println("Received:", msg2)
}
}
fmt.Println("-----------------------------------------------------------------------------------")
fmt.Println("-----------------------------------------------------------------------------------")
// Channel Select with Concurrent Workers
// This example demonstrates using select to handle multiple workers concurrently, each sending results back to a common channel
ch = make(chan string, 3)
// Start 3 workers
for i := 1; i <= 3; i++ {
go worker(i, ch)
}
// Using select in a loop to receive messages from workers
for i := 0; i < 3; i++ {
select {
case msg := <-ch:
fmt.Println(msg)
}
}
fmt.Println("-----------------------------------------------------------------------------------")
fmt.Println("-----------------------------------------------------------------------------------")
// Channel Select with Randomized Work
// The select statement handles different durations of work, simulating a more unpredictable flow of data
ch = make(chan string, 3)
// Function to simulate work that takes random time
doWork := func(id int) {
sleepTime := rand.Intn(3) + 1
time.Sleep(time.Duration(sleepTime) * time.Second)
ch <- fmt.Sprintf("Worker %d finished after %d seconds", id, sleepTime)
}
// Start 3 workers
for i := 1; i <= 3; i++ {
go doWork(i)
}
// Using select in a loop to receive messages from workers
for i := 0; i < 3; i++ {
select {
case msg := <-ch:
fmt.Println(msg)
}
}
fmt.Println("-----------------------------------------------------------------------------------")
fmt.Println("-----------------------------------------------------------------------------------")
// Multiple Channels with Select in Different Goroutines
// Use select in different goroutines to handle more complex scenarios with multiple channels
ch1 = make(chan string)
ch2 = make(chan string)
// Goroutine to send data to ch1
go func() {
time.Sleep(2 * time.Second)
ch1 <- "message from ch1"
}()
// Goroutine to send data to ch2
go func() {
time.Sleep(1 * time.Second)
ch2 <- "message from ch2"
}()
// Another goroutine that uses select to handle messages
go func() {
select {
case msg1 := <-ch1:
fmt.Println("Worker received:", msg1)
case msg2 := <-ch2:
fmt.Println("Worker received:", msg2)
}
}()
// Allow time for all operations to complete
time.Sleep(3 * time.Second)
fmt.Println("-----------------------------------------------------------------------------------")
}