錯誤的寫法:
這里的<-ch 是為了從channel 中讀取 數據,為了不使channel通道被寫滿,阻塞 go 協程數的創建。但是請注意,go workForDraw(v, &wg) 是不阻塞后續的<-ch 執行的,所以就一直go workForDraw(v, &wg) 拉起新的協程。這么是達不到控制協程并發數10 的目的
正確的寫法:
直接將<-ch 寫入workForDraw 方法里面的最后,這樣只有 該 go 協程的任務 workForDraw 完成之后才會執行 <-ch ,使channel管道中的緩沖釋放一個。
這樣就把 <-ch 和 go 協程持有的任務 workForDraw 強制綁定,只有完成任務才會 <-ch ,如果不完成,只要channel通道的緩沖不滿10 就可以繼續創建新的go 協程持有workForDraw。直到緩沖滿到10 為止
func ListenRedisQue() {ch := make(chan int, 10)var wg sync.WaitGroupfor {keyData, err := config.GetRedisClient().Keys(global.RedisQueueKey + "*").Result()fmt.Println("ListenRedisQue start for", keyData)if err != nil {fmt.Println("redis queue empty!!")return}for _, v := range keyData {ch <- 1wg.Add(1)go workForDraw(v, &wg, ch)}wg.Wait()}
}func workForDraw(queueKey string, wg *sync.WaitGroup, ch chan int) {defer wg.Done()<-ch
}
另外切記 在for 循環中,一定不能初始化 db,或者其他消耗資源,可循環使用的動作,要將初始化提到for之外,將資源以變量或者指針形式傳入 for 邏輯內部使用