第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

goroutine使用了外面的變量,造成閉包問題。怎么解決呢?

goroutine使用了外面的變量,造成閉包問題。怎么解決呢?

哆啦的時(shí)光機(jī) 2019-03-18 22:16:12
問題描述我有這樣一個(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ò)誤信息又是什么?
查看完整描述

2 回答

?
Cats萌萌

TA貢獻(xiàn)1805條經(jīng)驗(yàn) 獲得超9個(gè)贊

自己思考了一下。其實(shí),既然是閉包。那么,只要將item作為參數(shù),傳遞給這個(gè)循環(huán)goroutine,就可以了 
他作為形參,自然不會(huì)被修改

// 從out隊(duì)列接收數(shù)據(jù)
        for _,item := range result.Items {
            fmt.Println("got item: ",item)            go func(rec interface{}) {
                c.ItemChan <- rec
            }(item)
        }

帶緩沖的channel,我認(rèn)為不是一個(gè)好的辦法。因?yàn)?,緩沖終歸會(huì)滿。


查看完整回答
反對(duì) 回復(fù) 2019-03-18
?
縹緲止盈

TA貢獻(xiàn)2041條經(jīng)驗(yàn) 獲得超4個(gè)贊

你打印寫入的地方有問題。

for _,item := range result.Items {            //fmt.Println("got item: ",item)//把這個(gè)放 go func()里面
            go func() {
                fmt.Println("got item: ",item)
                c.ItemChan <- item
            }()
        }

這樣你打印的就和接收到的數(shù)據(jù)是一樣的了。
因?yàn)?code>go func 并不能保證立即執(zhí)行,在它還沒有執(zhí)行的時(shí)候,item值已經(jīng)被for循環(huán)改變了

我有個(gè)疑問,你在寫入的地方起goroutine是為了for循環(huán)不被寫入阻塞嗎?如果不想因?yàn)閷懭氡蛔枞?,可以給channel定義一個(gè)緩沖。按照例子的,緩沖數(shù)定義為items的數(shù)量即可


查看完整回答
反對(duì) 回復(fù) 2019-03-18
  • 2 回答
  • 0 關(guān)注
  • 488 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)