Бросок: все горуты спит - тупик

Учитывая следующую простую программу Go

package main

import (
    "fmt"
)

func total(ch chan int) {
    res := 0
    for iter := range ch {
        res += iter
    }
    ch <- res
}

func main() {
    ch := make(chan int)
    go total(ch)
    ch <- 1
    ch <- 2
    ch <- 3
    fmt.Println("Total is ", <-ch)
}

Мне интересно, может ли кто-нибудь просветить меня, почему я получаю

throw: all goroutines are asleep - deadlock!

Благодарю вас

Ответы

Ответ 1

Поскольку вы никогда не закрываете канал ch, цикл диапазона никогда не будет завершен.

Вы не можете отправить результат на том же канале. Решением является использование другого.

Ваша программа может быть адаптирована следующим образом:

package main

import (
    "fmt"
)

func total(in chan int, out chan int) {
    res := 0
    for iter := range in {
        res += iter
    }
    out <- res // sends back the result
}

func main() {
    ch := make(chan int)
    rch  := make(chan int)
    go total(ch, rch)
    ch <- 1
    ch <- 2
    ch <- 3
    close (ch) // this will end the loop in the total function
    result := <- rch // waits for total to give the result
    fmt.Println("Total is ", result)
}

Ответ 2

Это тоже правильно.

package main

import "fmt"

func main() {
    c := make(chan int)
    go do(c)
    c <- 1
    c <- 2
    // close(c)
    fmt.Println("Total is ", <-c)
}

func do(c chan int) {
    res := 0
    // for v := range c {
    //  res = res + v
    // }
    for i := 0; i < 2; i++ {
        res += <-c
    }
    c <- res
    fmt.Println("something")
}