Question

There are some cases you need to close channel and some cases that it is not necessary.

http://play.golang.org/p/piJHpZ2-aU

queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue)

for elem := range queue {
    fmt.Println(elem)
}

Here I am getting

fatal error: all goroutines are asleep - deadlock!

whereas this code's close is optional

http://play.golang.org/p/Os4T_rq0_B

jobs := make(chan int, 5)
done := make(chan bool)

go func() {
    for {
        j, more := <-jobs
        if more {
            fmt.Println("received job", j)
        } else {
            fmt.Println("received all jobs")
            done <- true
            return
        }
    }
}()

for j := 1; j <= 3; j++ {
    jobs <- j
    fmt.Println("sent job", j)
}
close(jobs)
fmt.Println("sent all jobs")

<-done
// close(done)
Was it helpful?

Solution

The first example the channel needs to be closed because of the usage of the range keyword. When range is used with a channel, it will continue to try to read from the channel until the channel is closed.

From http://golang.org/ref/spec#For_statements

[When using range for] ...channels, the iteration values produced are the successive values sent on the channel until the channel is closed. If the channel is nil, the range expression blocks forever.

Which means that you have to close the channel to exit the loop.

In the second example you are using the receive operator <-. This operator will block until one item can be pulled out of the channel. Since there is one item waiting in the channel to be delivered, it will yield immediately. In this case, close is optional because there are no other blocking operations on the channel after that, so it's just as happy to stay "open".

See the channels section for more details...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top