2 回答

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超4個(gè)贊
正如@AndrewN 指出的那樣,問(wèn)題是每個(gè) goroutine 都到達(dá)了它試圖發(fā)送到results通道的地步,但是這些發(fā)送將阻塞,因?yàn)閞esults通道沒(méi)有緩沖并且在for i := range results循環(huán)之前沒(méi)有從它們讀取任何內(nèi)容。你永遠(yuǎn)不會(huì)進(jìn)入那個(gè)循環(huán),因?yàn)槟闶紫刃枰瓿蒮or scanner.Scan()循環(huán),它試圖將所有的lines發(fā)送到lines通道,這是被阻塞的,因?yàn)?goroutines 永遠(yuǎn)不會(huì)循環(huán)回 ,range lines因?yàn)樗鼈儽豢ㄔ诎l(fā)送到results.
您可能會(huì)嘗試做的第一件事是將這些scanner.Scan()東西放在一個(gè) goroutine 中,以便可以立即開(kāi)始讀取results通道。但是,您將遇到的下一個(gè)問(wèn)題是知道何時(shí)結(jié)束for i := range results循環(huán)。您想要關(guān)閉results通道,但只有在原始 goroutine 完成讀取lines通道之后。您可以在關(guān)閉results頻道后立即關(guān)閉lines頻道,但是我認(rèn)為這可能會(huì)引入潛在的競(jìng)爭(zhēng),因此最安全的做法是在關(guān)閉results頻道之前等待原始兩個(gè) goroutine 完成:(操場(chǎng)鏈接):
package main
import "fmt"
import "runtime"
import "bufio"
import "strings"
import "sync"
func main() {
runtime.GOMAXPROCS(2)
scanner := bufio.NewScanner(strings.NewReader(`
hi mom
hi dad
hi sister
goodbye`))
lines := make(chan string)
results := make(chan int)
wg := sync.WaitGroup{}
for i := 0; i < 2; i++ {
wg.Add(1)
go func() {
for line := range lines {
fmt.Printf("%s\n", line)
results <- len(strings.Split(line, " "))
}
wg.Done()
}()
}
go func() {
for scanner.Scan() {
lines <- scanner.Text()
}
close(lines)
wg.Wait()
close(results)
}()
acc := 0
for i := range results {
acc += i
}
fmt.Printf("%d\n", acc)
}

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超10個(gè)贊
默認(rèn)情況下,go 中的通道是無(wú)緩沖的,這意味著您生成的匿名 goroutine 都不能發(fā)送到結(jié)果通道,直到您開(kāi)始嘗試從該通道接收。這不會(huì)在主程序中開(kāi)始執(zhí)行,直到scanr.Scan()完成填充線路通道......它被阻止執(zhí)行直到您的匿名函數(shù)可以發(fā)送到結(jié)果通道并重新啟動(dòng)它們的循環(huán)。僵局。
您的代碼中的另一個(gè)問(wèn)題,即使通過(guò)緩沖通道來(lái)微不足道地修復(fù)上述問(wèn)題,對(duì)于 i := range 結(jié)果也將在沒(méi)有更多結(jié)果輸入時(shí)死鎖,因?yàn)橥ǖ郎形搓P(guān)閉。
編輯:如果您想避免緩沖通道,這是一種潛在的解決方案。基本上,第一個(gè)問(wèn)題是通過(guò)一個(gè)新的 goroutine執(zhí)行發(fā)送到結(jié)果通道來(lái)避免的,允許行循環(huán)完成。第二個(gè)問(wèn)題(不知道何時(shí)停止讀取通道)可以通過(guò)在創(chuàng)建 goroutine 時(shí)對(duì)其進(jìn)行計(jì)數(shù)并在考慮到每個(gè) goroutine 時(shí)明確關(guān)閉通道來(lái)避免。用等待組做類似的事情可能會(huì)更好,但這只是展示如何無(wú)緩沖地執(zhí)行此操作的一種非??焖俚姆椒?。
- 2 回答
- 0 關(guān)注
- 203 瀏覽
添加回答
舉報(bào)