我正在编写一种将数字分为100组并同时计算阶乘的实践,但是我的代码给了我僵局。
我认为问题可能在于管道链的启动。由于所有函数都将通道作为参数,因此我不清楚为什么在主行{{1}时main中的go func不能将给定的in
通道值传递给genConcurrentGroup
函数}。
total:= <- c
答案 0 :(得分:0)
1。 total:= <- c //DEADLOCK HERE! Why?
您需要向in
频道添加一个缓冲区,因为发送该值时没有人收到。
2。 total := <-nums //DEADLOCK HERE! Why?
您需要添加sync.WaitGroup
以等待所有goroutine结束,然后您可以关闭频道以对其进行循环。
没有死锁的完整代码:
package main
import (
"fmt"
"sync"
)
func main() {
in := make(chan int, 1)
in <- 1005
out := calculateFacotorial(genConcurrentGroup(in))
fmt.Println(<-out)
}
//split input number into groups
//the result should be a map of [start number, number in group]
//this is not heavy task so run in one go routine
func genConcurrentGroup(c chan int) chan map[int]int {
out := make(chan map[int]int)
go func() {
//100 groups
total := <-c //DEADLOCK HERE! Why?
//element number in group
elemNumber := total / 100
extra := total % 100
result := make(map[int]int)
if elemNumber > 0 {
//certain 100 groups
for i := 1; i <= 99; i++ {
result[(i-1)*elemNumber+1] = elemNumber
}
result[100] = extra + elemNumber
} else {
//less than 100
for i := 1; i <= total; i++ {
result[i] = 1
}
}
out <- result
close(out)
}()
return out
}
//takes in all numbers to calculate multiply result
//this could be heavy so can do it 100 groups together
func calculateFacotorial(nums chan map[int]int) chan float64 {
out := make(chan float64)
total := <-nums //DEADLOCK HERE! Why?
go func() {
oneResult := make(chan float64, len(total))
var wg sync.WaitGroup
wg.Add(len(total))
for k, v := range total {
go func() {
t := 1.0
for i := 0; i < v; i++ {
t *= float64(k) + float64(i)
}
oneResult <- t
wg.Done()
}()
}
wg.Wait()
close(oneResult)
result := 1.0
for n := range oneResult {
result *= n
}
out <- result
}()
return out
}