elp*_*res 12 concurrency channel go
想法是在切片中具有可变数量的通道,将通过它们接收的每个值推送到单个通道中,并且在最后一个输入通道关闭时关闭该输出通道.这样的东西,但对于多个渠道超过两个:
func multiplex(cin1, cin2, cout chan int) {
n := 2
for {
select {
case v, ok := <-cin1:
if ok {
cout <- v
} else {
n -= 1
}
case v, ok := <-cin2:
if ok {
cout <- v
} else {
n -= 1
}
}
if n == 0 {
close(cout)
break
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码避免了繁忙的循环,因为没有任何default情况,这是好的(编辑:它看起来像",ok"的存在使得select语句非阻塞而且循环很忙.但是为了示例的缘故,把代码想象成会阻止它.使用任意数量的输入通道也可以实现相同的功能吗?显然,这可以通过将切片成对地减少到单个通道来完成,但如果可能的话,我会对更简单的解决方案更感兴趣.
Run*_*ild 26
我相信这个片段可以满足您的需求.我已经更改了签名,因此很明显输入和输出只能用于一个方向的通信.注意添加a sync.WaitGroup,你需要一些方法让所有输入信号表明它们已经完成,这很容易.
func combine(inputs []<-chan int, output chan<- int) {
var group sync.WaitGroup
for i := range inputs {
group.Add(1)
go func(input <-chan int) {
for val := range input {
output <- val
}
group.Done()
} (inputs[i])
}
go func() {
group.Wait()
close(output)
} ()
}
Run Code Online (Sandbox Code Playgroud)