チャネル別のゴルーチンプールを実現

行きは最近、内部サーバがHTTP要求で案内するために、Excelからのデータを使用し
ますが、無制限に追加できゴルーチンを開くには、ファイルを読んだ後、問題を発見した
カードが死んで以来、リードはすべてのカードの初期化要求を

シミュレーション問題

  • シミュレーションコード
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でゴルーチンを制限することはできませんだと思います
  • 使用する強力なBaiduは本当に兄はすでにコルーチンプールを書かれました
  • 私は、次のコードのコメントを追加しました
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()
}
  • 完璧なソリューション

おすすめ

転載: www.cnblogs.com/miaowoo/p/11412751.html