1.total:= <- c //DEADLOCK HERE! Why?
Вам необходимо добавить буфер в ваш in
канал, потому что никто не получает при отправке значения.
![enter image description here](https://i.stack.imgur.com/WuqKc.png)
2.total := <-nums //DEADLOCK HERE! Why?
Вам нужно добавить sync.WaitGroup
, чтобы дождаться окончания всех процедур, а затем вы можете закрыть свой канал, чтобы зациклить его.
![enter image description here](https://i.stack.imgur.com/F1GoU.png)
Полный код без блокировок:
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
}