Problem with goroutines in a for loop

I am trying to solve this problem on Exercism :

Write a program that takes into account the frequency of letters in texts using parallel computing.

Basically, I have a type FreqMap:

type FreqMap map[rune]int

And function Frequency:

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

Exercism provides an example implementation of a parallel version using recursion, but I would like to implement my own version using a loop for. I came up with the following solution that does not work:

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
}

It seems that it returns after 1 iteration c, it seems to contain the result of only 1 goroutine; I get the same result if I add sync.WaitGroup.

Could you explain what I am missing here?

Thank you in advance for your help!

+4
1

, , , ConcurrentFrequency . , - :

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
}

, , , :

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 , , , "", , . , , wg.Done . , , , - . wg.Wait, goroutines , , , ConcurrentFrequency . , ConcurrentFrequency, cannel , ( ) Frequency(s) .

+4
source

All Articles