小编典典

如何等待直到缓冲的通道(信号量)为空?

go

我有一个整数片,它们是同时操作的:

ints := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

我使用缓冲通道作为信号灯,以使并发运行go例程的上限:

sem := make(chan struct{}, 2)

for _, i := range ints {
  // acquire semaphore
  sem <- struct{}{}

  // start long running go routine
  go func(id int, sem chan struct{}) {
    // do something

    // release semaphore
    <- sem
  }(i, sem)
}

上面的代码在到达最后两个整数或最后两个整数之前都可以很好地工作,因为程序在这些最后执行例程完成之前就结束了。

问题 :如何等待缓冲的通道耗尽?


阅读 336

收藏
2020-07-02

共1个答案

小编典典

您不能以这种方式使用信号灯(在这种情况下为通道)。不能保证在处理值和调度更多goroutine时,它永远不会为空。在这种情况下,这尤其不重要,因为您正在同步调度工作,但是由于没有检查通道长度的无竞争方法,因此没有等待通道长度达到0的原语。

使用a sync.WaitGroup等待所有goroutine完成

sem := make(chan struct{}, 2)

var wg sync.WaitGroup

for _, i := range ints {
    wg.Add(1)
    // acquire semaphore
    sem <- struct{}{}
    // start long running go routine
    go func(id int) {
        defer wg.Done()
        // do something
        // release semaphore
        <-sem
    }(i)
}

wg.Wait()
2020-07-02