1
0
Fork 0
pr3-sose2026-fork/go/05-concurrency/select.go

63 lines
2.2 KiB
Go

package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
// Simulate some work by sleeping for a random duration between 1 and 5 seconds before sending a message to ch1.
time.Sleep(time.Duration(rand.Intn(5)+1) * time.Second)
ch1 <- "Message from channel 1"
}()
go func() {
// Simulate some work by sleeping for a random duration between 1 and 5 seconds before sending a message to ch2.
time.Sleep(time.Duration(rand.Intn(5)+1) * time.Second)
ch2 <- "Message from channel 2"
}()
// Create multiple dynamic channels and send messages to them in separate goroutines.
// This demonstrates how we can use select to wait for messages from a variable number of channels.
count := 10
var channels []chan string
for i := range count {
ch := make(chan string)
channels = append(channels, ch)
go func() {
time.Sleep(time.Duration(rand.Intn(5)+1) * time.Second)
ch <- fmt.Sprintf("Message from dynamic channel %d", i)
}()
}
// Fan-in pattern: Create a single channel to receive messages from multiple channels.
// This allows us to use select to wait for messages from all channels in a single case.
fanIn := make(chan string)
for _, ch := range channels {
go func(c chan string) {
fanIn <- <-c // Read a message from the dynamic channel and send it to the fanIn channel. A temporary variable is needed to capture the current value of ch.
}(ch)
}
// Use select to wait for messages from multiple channels. The select statement allows us to wait on multiple channel operations
// and proceed with the one that is ready first.
select {
case msg1 := <-ch1:
println("Received:", msg1)
case msg2 := <-ch2:
println("Received:", msg2)
case msg := <-fanIn:
println("Received:", msg)
case <-time.After(3 * time.Second): // The time.After function returns a channel that will send the current time after the specified duration. This case will be selected if no other channels are ready within 3 seconds, allowing us to handle a timeout scenario.
println("Timeout occurred")
//default: // The default case is executed if none of the channels are ready. Not to be used in this example, as it would cause the select statement to proceed immediately.
// println("Nothing")
}
}