Go channel 数据聚合

一个数据聚合模块的工作协程将多个数据流合为一个数据流(就是指有多个源 channel 输入、一个目的 channel 输出的情况)。

下面这个函数将任意数量的数据流合为一个。

e.g.

通过每个 goroutine 处理一个 channel 的方式来实现。

go 复制代码
func Aggregator(chs ...<-chan any) <-chan any {
 out := make(chan any)
 var wg sync.WaitGroup
 for _, ch := range chs {
  wg.Add(1)
  ch := ch
  go func() {
   defer wg.Done()
   for v := range ch {
    out <- v
   }
  }()
 }
 go func() {
  wg.Wait()
  close(out)
 }()
 return out
}

e.g.

通过反射的方式来实现,主要就是构造出 SelectCase slice,然后传递给 reflect.Select 语句。

go 复制代码
func AggregatorReflect(chs ...<-chan any) <-chan any {
 out := make(chan any)
 go func() {
  defer close(out)
  // 构造 SelectCase slice
  var cases []reflect.SelectCase
  for _, ch := range chs {
   cases = append(cases, reflect.SelectCase{
    Dir:  reflect.SelectRecv,
    Chan: reflect.ValueOf(ch),
   })
  }
  // 循环,从 cases 中选择一个可用的
  for len(cases) > 0 {
   i, v, ok := reflect.Select(cases)
   if !ok { // 此通道关闭并且它的缓冲队列中为空
    cases = append(cases[:i], cases[i+1:]...)
    continue
   }
   out <- v.Interface()
  }
 }()
 return out
}
相关推荐
步行cgn7 小时前
Spring c 命名空间注入详解
java·后端·spring
明月_清风7 小时前
Maven 到底是什么?一篇文章搞懂 Java 项目构建与依赖管理
java·后端·maven
明月_清风8 小时前
AI 越来越强,程序员真正的价值到底是什么?
人工智能·后端
aramae8 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
Rain的Java大神之路8 小时前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
码事漫谈9 小时前
别再跟AI说“请”了,它根本不 care——但有个东西它超在意
后端
郑州光合科技余经理11 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
IT_陈寒12 小时前
Vue的响应式让我熬到凌晨三点,原来漏了这个小细节
前端·人工智能·后端
颜进强12 小时前
01 · NestJS 是什么:用途、解决什么问题、与热门框架对比
前端·后端·ai编程
isfox12 小时前
MapReduce Shuffle 深度解析:数据从 Map 到 Reduce 的完整旅程
后端