Search code examples
gochannelgoroutine

How to implement these goroutines communication in below scene


Given a channel slice([]chan{}),how to realize that we accept these messages from the channel array.

I consider below 2 ways, but they can solve my problem:

  1. we can use "select", but the length of slice is not fixed, so the number of case is also not fixed.
  2. we can traverse the slice, but it will cause block when no msg can be received.

Solution

  • You can use the reflect package to select on a dynamic number channels.

    package main
    
    import (
        "fmt"
        "reflect"
        "time"
    )
    
    func main() {
        // Create a slice of channels
        channels := make([]chan string, 5)
    
        // Initialize the channels
        for i := range channels {
            channels[i] = make(chan string)
        }
    
        // Send messages to the channels
        go func() {
            for _, ch := range channels {
                time.Sleep(time.Second)
                ch <- "hello"
            }
        }()
    
        // Use reflect.Select to select on a set of channels in the slice
        for {
            cases := make([]reflect.SelectCase, len(channels))
            for i, ch := range channels {
                cases[i] = reflect.SelectCase{
                    Dir:  reflect.SelectRecv,
                    Chan: reflect.ValueOf(ch),
                }
            }
    
            // Wait for a message to be received on one of the channels
            i, v, ok := reflect.Select(cases)
    
            if !ok {
                fmt.Println("Channel closed")
                continue
            }
    
            // Print the received message and the index of the channel
            fmt.Printf("Received %q from channel %d\n", v.Interface(), i)
        }
    }