錯(cuò)誤的寫法:
這里的<-ch 是為了從channel 中讀取 數(shù)據(jù),為了不使channel通道被寫滿,阻塞 go 協(xié)程數(shù)的創(chuàng)建。但是請(qǐng)注意,go workForDraw(v, &wg) 是不阻塞后續(xù)的<-ch 執(zhí)行的,所以就一直go workForDraw(v, &wg) 拉起新的協(xié)程。這么是達(dá)不到控制協(xié)程并發(fā)數(shù)10 的目的
正確的寫法:
直接將<-ch 寫入workForDraw 方法里面的最后,這樣只有 該 go 協(xié)程的任務(wù) workForDraw 完成之后才會(huì)執(zhí)行 <-ch ,使channel管道中的緩沖釋放一個(gè)。
這樣就把 <-ch 和 go 協(xié)程持有的任務(wù) workForDraw 強(qiáng)制綁定,只有完成任務(wù)才會(huì) <-ch ,如果不完成,只要channel通道的緩沖不滿10 就可以繼續(xù)創(chuàng)建新的go 協(xié)程持有workForDraw。直到緩沖滿到10 為止文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-656445.html
func ListenRedisQue() {
ch := make(chan int, 10)
var wg sync.WaitGroup
for {
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 <- 1
wg.Add(1)
go workForDraw(v, &wg, ch)
}
wg.Wait()
}
}
func workForDraw(queueKey string, wg *sync.WaitGroup, ch chan int) {
defer wg.Done()
<-ch
}
另外切記 在for 循環(huán)中,一定不能初始化 db,或者其他消耗資源,可循環(huán)使用的動(dòng)作,要將初始化提到for之外,將資源以變量或者指針形式傳入 for 邏輯內(nèi)部使用文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-656445.html
到了這里,關(guān)于go 協(xié)程并發(fā)數(shù)控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!