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
}
相关推荐
雪隐1 小时前
个人电脑玩AI-16让5060 Ti给你打工——MiniMax H3 提速实录:从"泡杯茶等视频"到"视频等你",一张 5060 Ti 的自我修养
前端·人工智能·后端
952361 小时前
Sentinel
java·后端·spring·sentinel·springcloud
名字还没想好☜2 小时前
Go 的 sync.Cond 实战:用条件变量做等待/通知,比忙轮询省 CPU
开发语言·数据库·后端·golang·go
zzzll11112 小时前
Spring Boot 入门指南:从零开始构建微服务
spring boot·后端·微服务
运维行者_2 小时前
企业带宽监控工具实战:网络流量分析与异常排查的5个关键能力
运维·服务器·开发语言·网络·分布式·后端·php
长栎2 小时前
你用了五年的消息队列,不知道它背后站着中介者模式
后端
Gopher_HBo2 小时前
路由注册:RouterGroup(routergroup.go)
后端
用户608186527902 小时前
Avalonia UI 控件样式定义的三种方式详解
后端
feng尘3 小时前
volatile 可见性与内存屏障知识点
后端
SamDeepThinking3 小时前
第3篇:企业级CAS单点登录实战-技术架构设计方案
后端·程序员·架构