I'm coding a practice to split number into 100 groups and calculate factorial concurrently, however my code gives me deadlock.
I think the issue could be the pipeline chain initiation. Since all the functions are taking in channels as argument, I'm not clear about why the go func in main doesn't pass the given in
channel value to genConcurrentGroup
function when this line total:= <- c
happens.
package main
import "fmt"
func main() {
in := make (chan int)
out := make (chan float64)
go func() {
in <- 1005
out = calculateFacotorial(genConcurrentGroup(in))
}()
fmt.Println(<-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)
for k,v := range total{
go func() {
t := 1.0
for i:=0;i<v;i++{
t *= float64(k) + float64(i)
}
oneResult <- t
}()
}
result := 1.0
for n := range oneResult{
result *= n
}
close(oneResult)
}()
return out
}