我有以下情况:
我在频道上收到一条消息,告诉我上传文件。上传由阻止函数uploadToServer
完成。 zipGen
频道每秒可能收到几条消息,我想同时上传最多5个文件(不多,但可能更少 - 取决于第三个工作人员在zipGen
上发送的消息数量是多少超出了这个问题的范围)。
listenToZips
函数在go例程(go listenToZips()
函数的init
)内运行:
func listenToZips() {
for {
select {
case zip := <-zipGen:
uploadToServer(zip) // this is blocking
}
}
}
如果我启动go uploadToServer(zip)
而不是uploadToServer(zip)
- 我得到了太多的并发性(例如我的程序会尝试同时上传10个文件,但我希望最多5个) 。
另一方面,如果没有go uploadToServer(zip)
(仅使用上述函数中的uploadToServer(zip)
),我一次只上传一个文件(因为uploadToServer(zip)
正在阻止)。
如何实现此级别的控制以允许我同时最多上传5个文件?
谢谢!
答案 0 :(得分:3)
最简单的选项 - 预先设定N个goroutine,从通道获取输入,并在循环中上传它。在每个goroutine的上下文中,操作都将被阻塞,但是N goroutines会这样做。当然,只有一个goroutine会收到每条消息。
func listenToZips(concurrent int) {
for i:=0; i < concurrent; i++ {
// spawn a listener goroutine
go func() {
for {
select {
case zip := <-zipGen:
uploadToServer(zip) // this is blocking
}
}
}()
}
}
当然你可以添加停止条件,可能使用不同的频道,但基本思路是一样的。
答案 1 :(得分:1)
试试这个: https://github.com/korovkin/limiter
limiter := NewConcurrencyLimiter(10)
limiter.Execute(func() {
uploadToServer()
})
limiter.Wait()