2 回答

TA貢獻(xiàn)1906條經(jīng)驗(yàn) 獲得超10個(gè)贊
有些代碼路徑不會(huì)打印某些done消息。調(diào)度程序碰巧選擇了一個(gè)不為multiply. 如果您稍微更改代碼(例如,在與現(xiàn)在不同的實(shí)例上登錄),您會(huì)發(fā)現(xiàn)它也可能會(huì)丟失add done消息。(https://play.golang.org/p/meEPM5GR9Rr)。原因如下:
如果done消息在生成器將數(shù)字寫(xiě)入通道并且乘法器讀取它之后立即到達(dá),那么乘法器會(huì)看到done可用并選擇它。multiplier打印done消息時(shí)就是這種情況。如果done消息在 multiplier 在 for 循環(huán)中等待時(shí)到達(dá),則 multiplier 將接收輸入通道(而不是done通道)的關(guān)閉,導(dǎo)致 for 循環(huán)終止而不打印done消息。
出現(xiàn)問(wèn)題是因?yàn)槟趶?for 循環(huán)中的通道讀取,然后進(jìn)行選擇。在等待 for 循環(huán)從通道中讀取數(shù)據(jù)時(shí),不會(huì)評(píng)估與選擇相關(guān)的任何事件。
解決這個(gè)問(wèn)題的更好方法是不使用 for 循環(huán)從通道中讀取。例如:
for {
select {
case <-done:
return
case i, ok:= <-intstream:
if !ok {
return
}
select {
case <- done:
return
case addedStream <- i + additive:
}
}
}

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超8個(gè)贊
你的add和multiply例程不是永遠(yuǎn)的循環(huán),而是for ... range循環(huán)。因此,在每個(gè)循環(huán)的頂部,它們等待下一個(gè)整數(shù),而不是等待select接收關(guān)閉done或?qū)⒔Y(jié)果發(fā)送到它們的流。這不是問(wèn)題,但這意味著如果它們的輸入流關(guān)閉,它們將返回而不進(jìn)入循環(huán)本身。
如果我添加fmt.Println調(diào)用以暴露由于到達(dá)輸入流的末尾而退出的點(diǎn),則行為會(huì)略有變化(可能是由于時(shí)間的原因;我沒(méi)有費(fèi)心去解釋它,而B(niǎo)urak Serdar已經(jīng)發(fā)布了他的答案我正在輸入這個(gè)),輸出變?yōu)椋?/p>
add after select
2
multiply after select
generator after select
multiply after select
add after select
4
generator after select
multiply after select
add after select
6
generator after select
Closed done
done multiply !
add got end of stream - done!
finished iterating pipeline
generator after select
done generator!
ramaining goroutines: 1
finished!
通常更合理的是只讓生成器本身接收done信號(hào),并使流水線函數(shù)始終寫(xiě)入所有結(jié)果,這使得它們更可預(yù)測(cè)。當(dāng)然,讀取每個(gè)管道的人必須讀到最后——但你已經(jīng)在主 goroutine 中這樣做了,所以我們只是在整個(gè)過(guò)程中傳播它。 這是以這種方式執(zhí)行的代碼的簡(jiǎn)化版本;它輸出:
2
generator after select
4
generator after select
6
generator after select
Closed done
8
generator after select
done generator!
multiply got end of stream - done!
add got end of stream - done!
finished iterating pipeline
remaining goroutines: 1
請(qǐng)注意,這一次,我們從最終生成的值 (3) 中得到最終的計(jì)算值 (8)。
- 2 回答
- 0 關(guān)注
- 163 瀏覽
添加回答
舉報(bào)