在這段代碼中,我呼叫了一個函式來計算字串中字母的數量,并回傳一個符文圖。為了利用并發性,我使用 goroutine 呼叫該函式:
func ConcurrentFrequency(l []string) FreqMap {
var wg sync.WaitGroup
wg.Add(len(l))
m := FreqMap{}
// Using unbuffered channel
// ch := make(chan FreqMap, len(l))
ch := make(chan FreqMap)
for _, s := range l {
go func(s string, ch chan<- FreqMap) {
defer wg.Done()
ch <- Frequency(s)
}(s, ch)
}
go func() {
wg.Wait()
close(ch)
}()
for cm := range ch {
for r, n := range cm {
m[r] = n
}
}
return m
}
如果我在不使用等待組和關閉通道的 goroutine 的情況下嘗試此代碼:
go func() {
wg.Wait()
close(ch)
}()
,然后我陷入僵局。
我不明白的是,為什么我能夠遍歷無緩沖通道并從中讀取多個映射。
這是完整的程式: https ://go.dev/play/p/zUwr_HvTT5w
并發方法幾乎不比順序方法快:
goos: linux
goarch: amd64
pkg: letter
cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
BenchmarkSequentialFrequency
BenchmarkSequentialFrequency-2 2820 367128 ns/op 17571 B/op 13 allocs/op
BenchmarkConcurrentFrequency
BenchmarkConcurrentFrequency-2 4237 282632 ns/op 12682 B/op 72 allocs/op
PASS
ok letter 3.320s
uj5u.com熱心網友回復:
通道上的 for-range 回圈繼續進行,直到通道關閉。
如果您洗掉最終關閉通道的 goroutine,則 for 回圈將永遠無法終止。一旦所有的 goroutine 都發送了值,就只剩下一個 goroutine 了,它會被永遠阻塞,等待通道關閉。
緩沖通道與此問題無關。他們只幫助阻止發件人,但這里的問題是被阻止的接收者。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/473034.html
下一篇:Go程式列印星號而不是實際字符
