forked from steger/pr3-sose2026
63 lines
2.2 KiB
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")
|
|
}
|
|
}
|