当前位置 博文首页 > golang 40行代码实现通用协程池

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

    作者:xialeistudio 时间:2021-06-26 17:43

    代码仓库

    goroutine-pool

    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行代码实现通用协程池,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站长博客网站的支持!

    js
    下一篇:没有了