問題描述我有這樣一個(gè)程序,他從一個(gè)items列表中讀取items,然后,打印一下這個(gè)item,交個(gè)一個(gè)channel// 從out隊(duì)列接收數(shù)據(jù)
for _,item := range result.Items {
fmt.Println("got item: ",item) go func() {
c.ItemChan <- item
}()
}在另一個(gè)地方,起了一個(gè)goroutine,來接收 go func() {
count := 0
for {
item := <- out
count++
fmt.Printf("獲取到的item:%d,當(dāng)前saver計(jì)數(shù)count是:%d\n",item,count)
}
}()很簡(jiǎn)單的一個(gè)東西,但是發(fā)現(xiàn)。寫入是打印的item沒有重復(fù),但讀取的channel,打印有重復(fù)。 最后發(fā)現(xiàn)應(yīng)該是寫入是,channel阻塞,而外層循環(huán)還在繼續(xù),導(dǎo)致item更新了,然后在寫入channel的已經(jīng)是幾個(gè)相同的item了問題出現(xiàn)的環(huán)境背景及自己嘗試過哪些方法我嘗試給寫入添加sleep,這樣只要確保這個(gè)被消費(fèi)了,然后在寫入,就沒問題 for _,item := range result.Items {
time.Sleep(time.Millisecond * 100)
fmt.Println("got item: ",item) go func() {
c.ItemChan <- item
}()
}但顯然,這個(gè)不符合需求。那么,我的問題是,我有一個(gè)列表要不斷讀取,通過goroutine塞到一個(gè)channel里面,但這樣會(huì)造成閉包問題,該怎么解決呢?也許,將寫入改成一個(gè)大的goroutine是個(gè)好辦法? goroutine包裹整個(gè)for循環(huán),然后,此時(shí)在寫入channel就是阻塞的了相關(guān)代碼// 請(qǐng)把代碼文本粘貼到下方(請(qǐng)勿用圖片代替代碼)你期待的結(jié)果是什么?實(shí)際看到的錯(cuò)誤信息又是什么?
goroutine使用了外面的變量,造成閉包問題。怎么解決呢?
哆啦的時(shí)光機(jī)
2019-03-18 22:16:12