Issue
Consider the following code as a simplified example:
func printer(c <-chan int) {
for {
fmt.Print(<-c)
}
}
func provide() {
c := make(chan int)
go printer(c)
for i := 1; i <= 100; i++ {
c <- i
}
}
The function provide
creates a go routine printer
that prints the data provide
generates.
My question is, what happens after provide
returns and printer
starts blocking on the empty channel. Will the go routine leak, as there is no further reference to c
or will the garbage collector catch this case and dispose both the go routine and c
?
If it is indeed the case that this kind of code causes a memory leak, what strategies can I do to prevent such a memory leak from happening?
Solution
Close the channel. Reading from a closed channel always succeeds, returning a respective zero value. The optional second boolean returned value indicates validity of the first value.
A receive expression used in an assignment or initialization of the form
x, ok = <-ch
x, ok := <-ch
var x, ok = <-ch
yields an additional result of type
bool
reporting whether the communication succeeded. The value ofok
is true if the value received was delivered by a successful send operation to the channel, or false if it is a zero value generated because the channel is closed and empty.
func printer(c <-chan int) {
for {
v, ok := <-c
if !ok { // chan closed
return
}
// v is valid
fmt.Println(v)
}
}
func provide() {
c := make(chan int)
go printer(c)
for i := 1; i <= 100; i++ {
c <- i
}
close(c)
}
Answered By – zzzz
Answer Checked By – Willingham (GoLangFix Volunteer)