最近用到了 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() }
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() }