以下代码以致命错误结束:所有goroutines都处于睡眠状态 - 死锁!
// 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
}
这是输出:
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!
我的理解是范围等待来自通道的数据直到通道关闭,但是在for循环内或func()内部或之后添加close(ch)会使事情变得更糟(fmt.Println不会得到任何东西) - 尝试推迟(同样的问题)
什么是正确的方法?在这种情况下,范围不是正确的解决方案吗?
非常感谢!
答案 0 :(得分:4)
范围仅在通道关闭时停止。你正在陷入僵局,因为没有任何东西正在写入频道,但你正在等待写一些东西。您可以添加sync.WaitGroup
并在写入所有goroutine完成后关闭频道。
您可能还应该更改循环,因为有可能传递错误的值,因为您正在关闭可以同时更改的循环变量;这会更可靠:
for _, s := range l {
go func(s rune) {
ch <- Frequency(s)
}(s)
}
答案 1 :(得分:0)
我希望用于...选择以在频道中接收消息。
func main() {
in := State{[]What{A,B,C,D},[]What{},nil}
out := make(chan State)
go in.think(out)
life:=5
for {
select {
case s:=<-out:
fmt.Printf("out : %+v\n", s)
default:
time.Sleep(50 * time.Millisecond)
if life--;life==0 {
return
}
}
}
}