我有一段整数,这些整数是并发操作的:
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)
}上面的代码在到达最后一个或最后两个整数之前运行得很好,因为程序在完成最后一个go例程之前就结束了。
问题:如何等待缓冲通道耗尽?
发布于 2016-09-29 17:29:48
您不能以这种方式使用信号量(在本例中为通道)。在处理值和分配更多的goroutines时,不能保证它不会是空的。在这种情况下,这不是一个特别的问题,因为您是在同步地分配工作,但是因为没有无竞争的方法来检查通道的长度,所以没有基本的方法来等待一个通道的长度达到0。
使用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()发布于 2017-05-06 08:20:48
使用“员工池”处理数据。它比运行每个 int更便宜,为其中的变量分配内存等等。
ints := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
ch := make(chan int)
var wg sync.WaitGroup
// run worker pool
for i := 2; i > 0; i-- {
    wg.Add(1)
    go func() {
        defer wg.Done()
        for id := range ch {
            // do something
            fmt.Println(id)
        }
    }()
}
// send ints to workers
for _, i := range ints {
    ch <- i
}
close(ch)
wg.Wait()发布于 2016-09-29 17:35:52
很明显,没有人在等你的常规程序来完成。因此,程序结束之前,最后两个围棋例程完成.在程序结束之前,您可以使用一个工作组来等待所有的运行例程完成。这说明它更好- https://nathanleclaire.com/blog/2014/02/15/how-to-wait-for-all-goroutines-to-finish-executing-before-continuing/
https://stackoverflow.com/questions/39776481
复制相似问题