我有一个整数片,它们是同时操作的:
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) }
上面的代码在到达最后两个整数或最后两个整数之前都可以很好地工作,因为程序在这些最后执行例程完成之前就结束了。
问题 :如何等待缓冲的通道耗尽?
您不能以这种方式使用信号灯(在这种情况下为通道)。不能保证在处理值和调度更多goroutine时,它永远不会为空。在这种情况下,这尤其不重要,因为您正在同步调度工作,但是由于没有检查通道长度的无竞争方法,因此没有等待通道长度达到0的原语。
使用a sync.WaitGroup等待所有goroutine完成
sync.WaitGroup
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()