The following code ends with a fatal error: all goroutines are asleep - deadlock!
// Package letter returns the frequency of letters in texts using parallel computation.
package letter
import "fmt"
const testVersion = 1
type FreqMap map[rune]int
func Frequency(s string) FreqMap {
m := FreqMap{}
for _, r := range s {
m[r]++
}
return m
}
func ConcurrentFrequency(l []string) FreqMap {
ch := make(chan FreqMap)
for _, s := range l {
go func() {
ch <- Frequency(s)
}()
}
m := FreqMap{}
for c := range ch {
fmt.Println("channel:", c)
for k, v := range c {
m[k] += v
}
}
return m
}
This is output:
channel: map[121:8 101:42 98:8 104:28 102:6 71:1 59:1 97:33 110:15 103:15 112:6 109:5 116:38 10:7 87:2 107:1 108:17 99:3 117:7 39:5 79:4 114:27 105:15 44:7 119:8 100:12 63:2 65:1 118:3 45:1 32:72 111:18 115:24]
channel: map[97:33 110:15 111:18 117:7 108:17 45:1 115:24 10:7 79:4 32:72 121:8 100:12 105:15 63:2 107:1 71:1 119:8 114:27 103:15 102:6 65:1 44:7 87:2 118:3 101:42 98:8 116:38 39:5 112:6 104:28 109:5 99:3 59:1]
channel: map[99:3 116:38 104:28 108:17 44:7 117:7 119:8 114:27 10:7 87:2 110:15 100:12 103:15 107:1 32:72 111:18 102:6 59:1 45:1 101:42 109:5 63:2 115:24 97:33 105:15 112:6 65:1 71:1 79:4 121:8 98:8 39:5 118:3]
fatal error: all goroutines are asleep - deadlock!
My understanding is that range waits for data from channel until the channel is closed, but adding close(ch) inside the for loop, or inside the func() or after those, make things worse (the fmt.Println does not get anything) - tried also with defer (same problem)
What would be the correct approach? Isn't range the right solution in this case ?
Thanks a lot !