concurrency - 是否可以将多个 channel 复用为一个?

标签 concurrency go channel

这个想法是在一个 slice 中拥有可变数量的 channel ,将通过它们接收到的每个值推送到单个 channel 中,并在最后一个输入 channel 关闭后关闭此输出 channel 。像这样,但对于两个以上的 channel :

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
        }
    }
}

上面的代码避免了忙循环,因为没有 default 情况,这很好(编辑:看起来“,ok”的存在使得选择语句非阻塞,循环是毕竟很忙。但是为了这个例子,把代码想象成它会阻塞)。是否也可以通过任意数量的输入 channel 来实现相同的功能?显然,这可以通过将 slice 成对地减少到单个 channel 来完成,但如果可能的话,我会对更简单的解决方案更感兴趣。

最佳答案

我相信这个片段可以满足您的需求。我已经更改了签名,因此很明显输入和输出应该只用于一个方向的通信。注意添加了 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)
  } ()
}

关于concurrency - 是否可以将多个 channel 复用为一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10979608/

相关文章:

不要在 Atom 中工作

go - 初始化嵌套的匿名结构

asynchronous - Golang 持久 channel 接受来自多个函数调用的输入

api - 获取名称中带有空格的 channel 的统计信息

unit-testing - 即使映射删除了键条目,测试仍然失败

scala - 在 Scala 中使用 actor 时如何限制并发?

java - ExecutorService 实例的线程类型保证

haskell - haskell 的 future

google-app-engine - Google App Engine 中 channel 池的最佳方法

java - 后台线程复制集合并重新初始化原始集合,可能吗?