Почему все горутины спят? - PullRequest
0 голосов
/ 05 марта 2019

Ниже приведен код;

package main

import "fmt"

func main() {
    func1(1)
}

func func1(n int) {
    ch := make(chan int)
    ch <- 1
        for i := range ch {
            fmt.Println(i)
            fmt.Println(<-ch)
        }   
}

Когда я пытаюсь выполнить этот код, он выдает следующую ошибку:

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.func1(0x1, 0x432070)
    /tmp/sandbox451742015/main.go:11 +0x60
main.main()
    /tmp/sandbox451742015/main.go:6 +0x20

1 Ответ

0 голосов
/ 05 марта 2019

Ваш канал не буферизован, поэтому первая отправка по нему будет блокироваться, пока кто-то не получит от него.Но код, который будет получать от него, идет после этого, так что это «немедленный» тупик.

Вы можете сделать его небуферизованным как ch := make(chan int, 1), так что отправка не будет блокироваться, но тогда у вас будет одинgoroutine, у которого есть for range по каналу.Этот цикл завершается, только если канал закрывается, но вы никогда не закрываете его.И вы отправляете только одно значение, поэтому цикл блокируется, ожидая значений, которые он может получить, или канала, который будет закрыт.

Вам нужна другая процедура, которая когда-нибудь закроет канал.И внутри цикла, вам не нужно снова получать от канала, конструкция цикла уже делает это.i будет значением, полученным от канала.

Рабочий пример, который имеет какой-либо смысл:

func func1(n int) {
    ch := make(chan int)
    go func() {
        for i := 0; i < 5; i++ {
            ch <- i
        }
        close(ch)
    }()
    for i := range ch {
        fmt.Println(i)
    }
}

Это выводит (попробуйте его на Go Playground ):

0
1
2
3
4
...