gpt4 book ai didi

for-loop - for 循环中的 goroutines 问题

转载 作者:IT王子 更新时间:2023-10-29 01:20:11 24 4
gpt4 key购买 nike

我正在尝试在 Exercism 上解决这个问题:

Write a program that counts the frequency of letters in texts using parallel computation.

基本上,我有一个 FreqMap 类型:

type FreqMap map[rune]int

还有一个频率函数:

func Frequency(s string) FreqMap {
m := make(FreqMap)
for _, v := range s {
m[v]++
}
return m
}

Exercism 提供了一个使用递归实现并发版本的示例,但我想使用 for 循环实现我自己的版本。我想出了以下解决方案,但它不起作用:

func ConcurrentFrequency(l []string) FreqMap {
c := make(chan FreqMap)
for i := 0; i < len(l); i++ {
go func(i int) {
c <- Frequency(l[i])
}(i)
}
return <- c
}

这似乎只在 1 次迭代后返回,c 似乎只包含 1 个 goroutine 的结果;如果我添加 sync.WaitGroup,我会得到相同的结果。

你能解释一下我在这里遗漏了什么吗?

预先感谢您的帮助!

最佳答案

您的代码似乎只进行一次迭代,因为 ConcurrentFrequency 从 channel 返回第一个值,仅此而已。我猜你想要这样的东西:

func ConcurrentFrequency(l []string) chan FreqMap {
c := make(chan FreqMap)
go func() {
var wg sync.WaitGroup
wg.Add(len(l))
for _, s := range l {
go func(s string) {
defer wg.Done()
c <- Frequency(s)
}(s)
}
wg.Wait()
close(c)
}()
return c
}

现在它返回 map channel ,这些你可能想合并成一个 map :

func main() {
m := make(FreqMap)
for v := range ConcurrentFrequency([]string{"foo", "bar","zoo"}) {
for k, v := range v {
m[k] += v
}
}
fmt.Println(m)
}

不适合评论的较长解释:

for _, s := range l 循环中,所有 goroutines 写入同一个 channel ,但由于该 channel 没有缓冲,一旦第一个值写入其中,它就是“full”,意味着不能向其中写入其他值。所以循环中只有一个 goroutine 可以完成,并且 wg.Done 只被调用一次。因此,如果源数组有多个字符串,其余的 gorutine 将无法完成,直到某些东西开始使用 channel 中的值。但在您的版本中,它会卡在 wg.Wait 中,因为并非所有 goroutine 都已完成,因此 ConcurrentFrequency 无法将 channel 返回给消费者。在我编写 ConcurrentFrequency 的方式中,可以将 cannel 返回给消费者,这(从 channel 读取)使其他 Frequency(s) 调用能够写入 channel .

关于for-loop - for 循环中的 goroutines 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38279990/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com