如何收听N个频道? (动态选择语句)

2023-12-13

要开始执行两个 goroutine 的无限循环,我可以使用下面的代码:

收到消息后,它将启动一个新的 goroutine 并永远持续下去。

c1 := make(chan string)
c2 := make(chan string)

go DoStuff(c1, 5)
go DoStuff(c2, 2)

for ; true;  {
    select {
    case msg1 := <-c1:
        fmt.Println("received ", msg1)
        go DoStuff(c1, 1)
    case msg2 := <-c2:
        fmt.Println("received ", msg2)
        go DoStuff(c2, 9)
    }
}

我现在希望 N 个 goroutine 有相同的行为,但是在这种情况下 select 语句会是什么样子呢?

这是我开始的代码位,但我很困惑如何编写 select 语句

numChans := 2

//I keep the channels in this slice, and want to "loop" over them in the select statemnt
var chans = [] chan string{}

for i:=0;i<numChans;i++{
    tmp := make(chan string);
    chans = append(chans, tmp);
    go DoStuff(tmp, i + 1)

//How shall the select statment be coded for this case?  
for ; true;  {
    select {
    case msg1 := <-c1:
        fmt.Println("received ", msg1)
        go DoStuff(c1, 1)
    case msg2 := <-c2:
        fmt.Println("received ", msg2)
        go DoStuff(c2, 9)
    }
}

您可以使用Select函数从reflect包裹:

func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool)

Select 执行案例列表描述的选择操作。喜欢 Go select 语句,它会阻塞,直到至少有一种情况可以 继续,做出统一的伪随机选择,然后执行 案件。它返回所选案例的索引,如果该案例是 接收操作,接收到的值和一个布尔值指示是否 该值对应于通道上的发送(而不是零 因为通道关闭而收到的值)。

你传入一个数组SelectCase结构体标识要选择的通道、操作的方向以及在发送操作的情况下要发送的值。

所以你可以这样做:

cases := make([]reflect.SelectCase, len(chans))
for i, ch := range chans {
    cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
}
chosen, value, ok := reflect.Select(cases)
// ok will be true if the channel has not been closed.
ch := chans[chosen]
msg := value.String()

您可以在这里尝试一个更充实的示例:http://play.golang.org/p/8zwvSk4kjx

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何收听N个频道? (动态选择语句) 的相关文章

随机推荐