要开始执行两个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) } }
您可以使用reflect包中的Select函数执行此操作:
Select
func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) Select执行案例列表中描述的选择操作。类似于Go select语句,它阻塞直到至少一种情况可以继续进行,做出统一的伪随机选择然后执行该情况。它返回所选案例的索引,如果该案例是接收操作,则返回接收到的值和一个布尔值,指示该值是否对应于通道上的发送(而不是由于通道关闭而接收到的零值)。
func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool)
Select执行案例列表中描述的选择操作。类似于Go select语句,它阻塞直到至少一种情况可以继续进行,做出统一的伪随机选择然后执行该情况。它返回所选案例的索引,如果该案例是接收操作,则返回接收到的值和一个布尔值,指示该值是否对应于通道上的发送(而不是由于通道关闭而接收到的零值)。
您传递一个SelectCase结构数组,这些结构标识要选择的通道,操作的方向以及在发送操作的情况下要发送的值。
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