2 回答
TA貢獻(xiàn)1900條經(jīng)驗(yàn) 獲得超5個(gè)贊
我認(rèn)為您遇到了僵局,因?yàn)槟鷉unc2只消耗了1 個(gè)值ch,然后完成。然后其他func1goroutine 被卡住等待ch可以寫入,他們不能這樣做,因?yàn)閏h在另一端沒有其他 goroutine 可以讀取。
由于您希望func2從chuntil開始持續(xù)消耗值ch,因此您需要func2像這樣創(chuàng)建一個(gè)循環(huán):
func func2(ch chan int) {
fmt.Println("func2")
for v := range ch {
fmt.Println(v)
}
}
這將保持func2“活躍”并閱讀,ch直到你在close(ch)其他地方做。在您的示例中關(guān)閉的適當(dāng)位置ch可能在mainafter wg.Wait()。
如果您想確保Println在程序完成之前看到所有語(yǔ)句的結(jié)果,您還應(yīng)該使用一些同步機(jī)制來(lái)等待func2完成。否則main將立即結(jié)束,之后close(ch)可能會(huì)或可能不會(huì)在func2打印收到的每個(gè)值之前。
一種常見的技術(shù)是“完成”通道。例如:
func func2(ch chan int, done chan bool) {
fmt.Println("func2")
for v := range ch {
fmt.Println(v)
}
done <- true
}
并在main:
done := make(chan bool)
go func2(ch, done)
...
wg.Wait()
close(ch)
<-done
使用chan struct{}(empty struct) 也很常見,因?yàn)榭战Y(jié)構(gòu)不需要內(nèi)存。
TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超4個(gè)贊
您正在尋找的是一種在所有值都完成流式傳輸時(shí)關(guān)閉通道的干凈方法。當(dāng)新值出現(xiàn)時(shí),您可以創(chuàng)建一個(gè)新通道并開始在此流式傳輸值。我就是這樣做的,也許有幫助
var wg sync.WaitGroup
toUpdate := make(chan *someType, BufferSize)
for i := 0; i < BufferSize; i++ {
go processEvents(toUpdate, &wg)
}
// // wait till all the checks have come back
go func(toUpdate chan * someType, group *sync.WaitGroup) {
group.Wait()
close(toCreate)
}(toCreate, toUpdate, &wg)
- 2 回答
- 0 關(guān)注
- 129 瀏覽
添加回答
舉報(bào)
