欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

golang 40行代码实现通用协程池

程序员文章站 2022-03-31 13:52:07
代码仓库 golang的协程管理 golang协程机制很方便的解决了并发编程的问题,但是协程并不是没有开销的,所以也需要适当限制一下数量。 不使用协程池的代码(示...

代码仓库

golang的协程管理

golang协程机制很方便的解决了并发编程的问题,但是协程并不是没有开销的,所以也需要适当限制一下数量。

不使用协程池的代码(示例代码使用chan实现,代码略啰嗦)

func (p *converter) upload(bytes [][]byte) ([]string, error) {
  ch := make(chan struct{}, 4)
  wg := &sync.waitgroup{}
  wg.add(len(bytes))
  ret := make([]string, len(bytes))
  // 上传
  for index, item := range bytes {
    ch <- struct{}{}
    go func(index int, imagedata []byte) {
      defer func() {
        wg.done()
        <-ch
      }()
      link, err := qiniu.uploadbinary(imagedata, fmt.sprintf("%d.png", time.now().unixnano()))
      if err != nil {
        log.println("上传图片失败", err.error())
        return
      }
      ret[index] = link
    }(index, item)
  }
  wg.wait()
  return ret, nil
}

需要实现的需求有两个:

限制最大协程数,本例为4

等待所有协程完成,本例为bytes切片长度

使用协程池的代码

func (p *converter) upload(bytes [][]byte) ([]string, error) {
  ret := make([]string, len(bytes))
  pool := goroutine_pool.new(4, len(bytes))

  for index, item := range bytes {
    index := index
    item := item
    pool.submit(func() {
      link, err := qiniu.uploadbinary(item, fmt.sprintf("%d.png", time.now().unixnano()))
      if err != nil {
        log.println("上传图片失败", err.error())
        return
      }

      ret[index] = link
    })
  }
  pool.wait()
  return ret, nil
}

可以看到最大的区别是只需要关注业务逻辑即可,并发控制和等待都已经被协程池接管

总结

以上所述是小编给大家介绍的golang 40行代码实现通用协程池,希望对大家有所帮助