如何在下面的场景中实现这些goroutine之间的通信?

huangapple go评论69阅读模式
英文:

How to implement these goroutines communication in below scene

问题

给定一个通道切片([]chan{}),如何实现从通道数组中接收这些消息。

我考虑了以下两种方法,但它们都可以解决我的问题:

  1. 我们可以使用"select"语句,但是切片的长度是不固定的,所以case的数量也是不固定的。
  2. 我们可以遍历切片,但是当没有消息可以接收时,会导致阻塞。
英文:

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.

答案1

得分: 0

你可以使用reflect包来选择动态数量的通道。

package main

import (
    "fmt"
    "reflect"
    "time"
)

func main() {
    // 创建一个通道切片
    channels := make([]chan string, 5)

    // 初始化通道
    for i := range channels {
        channels[i] = make(chan string)
    }

    // 向通道发送消息
    go func() {
        for _, ch := range channels {
            time.Sleep(time.Second)
            ch <- "hello"
        }
    }()

    // 使用reflect.Select在切片中选择一组通道
    for {
        cases := make([]reflect.SelectCase, len(channels))
        for i, ch := range channels {
            cases[i] = reflect.SelectCase{
                Dir:  reflect.SelectRecv,
                Chan: reflect.ValueOf(ch),
            }
        }

        // 等待从其中一个通道接收到消息
        i, v, ok := reflect.Select(cases)

        if !ok {
            fmt.Println("通道已关闭")
            continue
        }

        // 打印接收到的消息和通道的索引
        fmt.Printf("从通道 %d 接收到 %q\n", i, v.Interface())
    }
}

希望对你有帮助!

英文:

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

package main

import (
    &quot;fmt&quot;
    &quot;reflect&quot;
    &quot;time&quot;
)

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 &lt;- &quot;hello&quot;
        }
    }()

    // 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(&quot;Channel closed&quot;)
            continue
        }

        // Print the received message and the index of the channel
        fmt.Printf(&quot;Received %q from channel %d\n&quot;, v.Interface(), i)
    }
}

huangapple
  • 本文由 发表于 2023年3月9日 18:06:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75683089.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定