duanlao6573 2013-12-03 12:13
浏览 38
已采纳

如何在数量众多的goroutine提供的通道上阻止(并加入)?

I have a recursive function. The function will call itself with various different values depending on the data it gets, so the arity and depth of recursion is not known: each call may call itself zero or more times. The function may return any number of values.

I want to parallelise it by getting goroutines and channels involved. Each recursion of inner runs in its own goroutine, and sends back a value on the channel. The outer function deals with those values.

func outer(response []int) {

  results := make([]int)
  resultsChannel := make(chan int)

  inner := func(...) {
      resultsChannel <- «some result»;

      // Recurse in a new goroutine.
      for _, recursionArgument in «some calculated data» {
          go inner(recursionArgument)
      }
  }

  go inner(«initial values»);

  for {
      result := <- resultsChannel
      results = append(results, result)

      // HELP! How do I decide when to break?
  }

  return results
}

The problem comes with escaping the results channel loop. Because of the 'shape' of the recursion (unknown arity and depth) I can't say "finish after n events" and I can't send a sentinel value.

How do I detect when all my recursions have happened and return from outer? Is there a better way to approach this?

  • 写回答

1条回答 默认 最新

  • dsbj66959 2013-12-03 14:53
    关注

    You can use a sync.WaitGroup to manage the collection of goroutines you spawn: call Add(1) before spawning each new goroutine, and Done when each goroutine completes. So something like this:

    var wg sync.WaitGroup
    inner := func(...) {
        ...
        // Recurse in a new goroutine.
        for _, recursionArgument := range «some calculated data» {
              wg.Add(1)
              go inner(recursionArgument)
        }
        ...
        wg.Done()
    }
    wg.Add(1)
    go inner(«initial values»)
    

    Now waiting on wg will tell you when all the goroutines have completed.

    If you are reading the results from a channel, the obvious way to tell when there are no more results is by closing the channel. You can achieve this through another goroutine to do this for us:

    go func() {
        wg.Wait()
        close(resultsChannel)
    }()
    

    You should now be able to simply range over resultsChannel to read all the results.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题