0
votes

Following is the code;

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)
        }   
}

When I try to execute this code, it throws the following error;

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

1 Answers

2
votes

Your channel is unbuffered, so the first send on it will block until someone receives from it. But the code that would receive from it is after that, so this is an "immediate" deadlock.

You could make it unbuffered like ch := make(chan int, 1), so the send would not block, but then you have a single goroutine that has a for range over a channel. This loop only exits if the channel gets closed, but you never close it. And you only send a single value on it, so the loop is blocked, waiting on values that it can receive or the channel to get closed.

You need another goroutine that closes the channel sometime. And inside the loop, you do not need to receive again from the channel, the loop construct already does that. i will be a value received from the channel.

Working example that makes any sense:

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)
    }
}

This outputs (try it on the Go Playground):

0
1
2
3
4