为了账号安全,请及时绑定邮箱和手机立即绑定

我不明白为什么这适用于无缓冲通道,或者为什么需要等待组

我不明白为什么这适用于无缓冲通道,或者为什么需要等待组

Go
幕布斯7119047 2022-12-13 16:02:01
在这段代码中,我调用了一个函数来计算字符串中字母的数量,并返回一个符文图。为了利用并发性,我使用 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个赞

道上的 for-range 循环会一直持续到通道关闭为止

如果删除最终关闭通道的 goroutine,则 for 循环永远不会终止。一旦所有的 goroutines 发送值都完成了,就只剩下一个 goroutine 并且它被永远阻塞,等待通道关闭。

缓冲通道与此问题无关。他们只帮助处理被阻止的发件人,但这里的问题是被阻止的接收者。


查看完整回答
反对 回复 2022-12-13
  • 1 回答
  • 0 关注
  • 49 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信