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