Golang:限制阻塞操作的并发级别

时间:2015-09-02 13:02:05

标签: go

我有以下情况: 我在频道上收到一条消息,告诉我上传文件。上传由阻止函数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个文件?

谢谢!

2 个答案:

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