这个问题在这里已经有了答案:
Is there buffered lock pattern?
(1 个回答)
2年前关闭。
我想为 goroutine 中的一段代码设置并发限制。
我看了mutex
, channel ,但无法做到这一点。
m.Lock()
// make request to server
log.Info("Calling server for " + name)
resp, err := netClient.Do(req)
m.Unlock()
log.Info("outside lock for " + name)
使用上面的代码片段,我可以一个接一个地限制服务器调用。
相反,有没有一种方法可以让 4 个 goroutine 执行这个调用。只有在这 4 个中的任何一个响应后,另一个 goroutine 才能执行它。
所以我一次需要 4 个 goroutine 在 block 内。
提前致谢。
最佳答案
这里的答案是信号量。
这是一个片段:
package main
import (
"fmt"
"sync"
)
func main() {
numOfGoroutines := 4
sem := make(chan struct{}, numOfGoroutines)
wg := sync.WaitGroup{}
for i := 0; i < 100; i++ {
sem <- struct{}{}
wg.Add(1)
go func(i int) {
defer func() { <-sem }()
defer wg.Done()
fmt.Println(i)
}(i)
}
wg.Wait()
fmt.Println("done")
}
这个片段有一个重要的细节,链接中缺少 Peter提及。该片段在继续之前等待所有 goroutine 完成。
此外,Go 实现了 a weighted semaphore .
关于go - 如何保证一段代码执行不超过n次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61387371/