91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何通過Channel實現Goroutine Pool

發布時間:2021-09-19 11:17:37 來源:億速云 閱讀:347 作者:小新 欄目:大數據

這篇文章主要為大家展示了“如何通過Channel實現Goroutine Pool”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“如何通過Channel實現Goroutine Pool”這篇文章吧。

最近用到了 Go 從 Excel 導數據到服務器內部 用的是 http 請求
但是發現一個問題 從文件讀取之后 新開 Goroutine 會無限制新增
導致全部卡在初始化請求 于是乎就卡死了

問題模擬

  • 模擬代碼

func main() {
    pool := sync.WaitGroup{}
    for i := 0; i < 500; i++ {
        pool.Add(1)
        go func(i int) {
            resp, err := http.Get("http://ip.3322.org")
            if err != nil {
                fmt.Println(i, err)
            } else {
                defer resp.Body.Close()
                result, _ := ioutil.ReadAll(resp.Body)
                fmt.Println(i, string(result))
            }
            pool.Done()
        }(i)
    }
    pool.Wait()
}
  • 數量小的情況下 沒有問題 但是數量比較大的情況 就會發現程序直接卡死 一段時間之后報錯 并且沒有發出任何請求

問題解決

  • 實際上看的出來 是應為同時發起了太多的HTTP請求 導致系統卡死 數據沒有發送

  • 想到我在Java中用Thread提交請求 我就考慮 可不可限制 Goroutine 的數量

  • 使用強大的百度 果然找到了大佬已經寫好的協程池

  • 代碼如下 我加上了注釋

package gopool

import (
    "sync"
)

// Pool Goroutine Pool
type Pool struct {
    queue chan int
    wg    *sync.WaitGroup
}

// New 新建一個協程池
func New(size int) *Pool {
    if size <= 0 {
        size = 1
    }
    return &Pool{
        queue: make(chan int, size),
        wg:    &sync.WaitGroup{},
    }
}

// Add 新增一個執行
func (p *Pool) Add(delta int) {
    // delta為正數就添加
    for i := 0; i < delta; i++ {
        p.queue <- 1
    }
    // delta為負數就減少
    for i := 0; i > delta; i-- {
        <-p.queue
    }
    p.wg.Add(delta)
}

// Done 執行完成減一
func (p *Pool) Done() {
    <-p.queue
    p.wg.Done()
}

// Wait 等待Goroutine執行完畢
func (p *Pool) Wait() {
    p.wg.Wait()
}
  • 然后修改剛才的測試方法

package main

import (
    "io/ioutil"
    "log"
    "net/http"
    "yumc.pw/cloud/lib/gopool"
)

func main() {
    // 這里限制5個并發
    pool := gopool.New(5)// sync.WaitGroup{}
    for i := 0; i < 500; i++ {
        pool.Add(1)
        go func(i int) {
            resp, err := http.Get("http://ip.3322.org")
            if err != nil {
                fmt.Println(i, err)
            } else {
                defer resp.Body.Close()
                result, _ := ioutil.ReadAll(resp.Body)
                fmt.Println(i, string(result))
            }
            pool.Done()
        }(i)
    }
    pool.Wait()
}

以上是“如何通過Channel實現Goroutine Pool”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

商都县| 贺兰县| 卓尼县| 个旧市| 买车| 册亨县| 昌宁县| 黎城县| 襄垣县| 庆阳市| 肃宁县| 剑阁县| 定南县| 龙州县| 石景山区| 安陆市| 延安市| 闽清县| 化州市| 岳池县| 瑞丽市| 三亚市| 江华| 美姑县| 新蔡县| 汝阳县| 长泰县| 新沂市| 阜平县| 平谷区| 治县。| 多伦县| 陇川县| 锡林浩特市| 云南省| 景德镇市| 吴桥县| 衡东县| 福海县| 克什克腾旗| 长岭县|