go - 如何等到缓冲 channel (信号量)为空?

标签 go semaphore channel goroutine

我有一片整数,它们是并发操作的:

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

我使用缓冲 channel 作为信号量,以便获得并发运行的 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 例程完成之前结束。

问题:如何等待缓冲 channel 耗尽?

最佳答案

您不能以这种方式使用信号量(在本例中为 channel )。当您处理值和分派(dispatch)更多 goroutine 时,无法保证它在任何时候都不会为空。在这种情况下,这不是一个问题,特别是因为您正在同步调度工作,但是因为没有无竞争的方式来检查 channel 的长度,所以没有等待 channel 长度达到 0 的原语。

使用 sync.WaitGroup 等待所有 goroutines 完成

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()

关于go - 如何等到缓冲 channel (信号量)为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39776481/

相关文章:

node.js - NodeJS 回调 : tracking db calls so I can terminate the process

c - Sem_open导致非法寻道错误

go - 使用指向 channel 的指针

go - 打开数据通道的请求不包含 token

string - 将字符串 slice 转换为指向字符串的指针 slice

ios - 自从升级到 iOS10 后,带有 NSRunLoop 的信号量无法正常工作

java - 是否可以在 Java 和/或 Android 中使用 NIO Selector for FileChannels?

去 channel 和死锁

json - 如何从JSON解析值。我正在尝试列出单个值,例如python中的字典

python - 如何使用golang使用ecdsa私钥对消息进行签名?