2 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超7個(gè)贊
您的代碼中存在多個(gè)問(wèn)題。
在循環(huán)中,您正在生成多個(gè) (3) goroutines 運(yùn)行func2
,并且在中func2
,您將數(shù)據(jù)發(fā)送到ch2
并調(diào)用close(ch2)
。這是個(gè)問(wèn)題。ch2
當(dāng)一個(gè) goroutine 將數(shù)據(jù)發(fā)送到時(shí),另一個(gè)goroutine 可能會(huì)關(guān)閉該通道,這會(huì)導(dǎo)致:
panic: close of closed channel
goroutine 6 [running]:
main.func2(0xc00006c000, 0xc000056180)
? ? /home/projects/go-tuts/pipeline-loop.go:36 +0x72
created by main.main
? ? /home/projects/go-tuts/pipeline-loop.go:16 +0x10f
exit status 2
通常,您不需要多次關(guān)閉通道 - 您只需要在它們?nèi)客瓿珊箨P(guān)閉它們。WaitGroup
為此你需要另一個(gè);您需要將兩個(gè)函數(shù)都傳遞給 a?WaitGroup
。
更新:
我個(gè)人使用一種“工作”模式,將數(shù)據(jù)生成到同一通道,并且在完成所有工作后需要關(guān)閉該通道:
for something {
? ? wg.Add(1)
? ? go func(i int) {
? ? ? ? work(ch)
? ? ? ? wg.Done()
? ? }
}
go func() {
? ? wg.Wait()
? ? close()
}()
我認(rèn)為保持 API 清潔是一個(gè)好主意,WorkGroup因?yàn)閃orkGroup它是關(guān)于如何同步工作而不是如何完成工作的。
我已將您的代碼更改為這種模式:https ://play.golang.org/p/vdCNsxWhgyQ

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超6個(gè)贊
我懷疑您只希望一個(gè)通道從 ch1 讀取并寫入 ch2。創(chuàng)建 3 個(gè) go-routines 來(lái)做同樣的事情沒(méi)有多大意義(而且你最終也會(huì)關(guān)閉相同的通道 multiple time 這會(huì)導(dǎo)致恐慌,正如 leaf bebop 指出的那樣)
func main() {
ch1 := make(chan int, 10) // Use buffered channel so as to avoid clogging
ch2 := make(chan string, 10)
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func1(i, ch1, &wg)
}
go func2(ch1, ch2)
wg.Wait()
close(ch1)
for val := range ch2 {
fmt.Println(val)
}
}
- 2 回答
- 0 關(guān)注
- 208 瀏覽
添加回答
舉報(bào)