在这段代码中,我调用了一个函数来计算字符串中字母的数量,并返回一个符文图。为了利用并发性,我使用 goroutines 调用该函数: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: linuxgoarch: amd64pkg: lettercpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHzBenchmarkSequentialFrequencyBenchmarkSequentialFrequency-2 2820 367128 ns/op 17571 B/op 13 allocs/opBenchmarkConcurrentFrequencyBenchmarkConcurrentFrequency-2 4237 282632 ns/op 12682 B/op 72 allocs/opPASSok letter 3.320s
1 回答
jeck猫
TA贡献1909条经验 获得超7个赞
如果删除最终关闭通道的 goroutine,则 for 循环永远不会终止。一旦所有的 goroutines 发送值都完成了,就只剩下一个 goroutine 并且它被永远阻塞,等待通道关闭。
缓冲通道与此问题无关。他们只帮助处理被阻止的发件人,但这里的问题是被阻止的接收者。
- 1 回答
- 0 关注
- 67 浏览
添加回答
举报
0/150
提交
取消