golang40行代碼實現通用協程池

代碼倉庫

goroutine-poolgit

golang的協程管理

golang協程機制很方便的解決了併發編程的問題,可是協程並非沒有開銷的,因此也須要適當限制一下數量。github

不使用協程池的代碼(示例代碼使用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
}

須要實現的需求有兩個:golang

  1. 限制最大協程數,本例爲4
  2. 等待全部協程完成,本例爲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
}

能夠看到最大的區別是隻須要關注業務邏輯便可,併發控制和等待都已經被協程池接管編程

寫在最後

但願本文能減輕你控制協程的負擔併發

相關文章
相關標籤/搜索