首页 > 解决方案 > 使用通道的 MapReduce 任务

问题描述

我的函数下载数据,解析它并返回一些结果。我想同时启动该函数的多个实例并总结它们的结果。这是我使用的解决方案Mutex

var lock sync.Mutex
increment := func(data engine2.DownloadResult) {
    lock.Lock()
    defer lock.Unlock()
    albums += data.Album
    singles += data.Single
}

var wg sync.WaitGroup
foo := func(id uint) {
    defer wg.Done()
    result := engine.DownloadPlaylist(id)
    increment(*result)
}

for _, playlist := range repository.PlaylistRepository.Fetch() {
    wg.Add(1)
    go foo(playlist.Id)
}

wg.Wait()

据我所知channels,Go 中推荐使用同步机制。你能告诉我如何使用频道重写这个任务吗?

标签: go

解决方案


有多种使用渠道的解决方案。一个可能看起来像这样:

ch := make(chan *engine2.DownloadResult)
wg := sync.WaitGroup()
go func() {
   for result := range ch {
      increment_without_lock(result)
   }
}()
for _, playlist := range repository.PlaylistRepository.Fetch() {
    id := playlist.Id
    wg.Add(1)
    go func() {
       defer wg.Done()
       ch <- engine.DownloadPlaylist(id)
    }()
}
wg.Wait()
close(ch)

推荐阅读