1. Is it reasonable to expect the runtime to garbage collect these
goroutines, considering there are no other references to the channel
they're blocked on?
2. Is there a clean way to exit a goroutine when it is no longer
needed? One could close the channel in foo, but then the goroutine
would always have to check if the channel were closed before writing
to it. Or one could attach a side channel, but that feels cumbersome.
-Dan
package main
func pump() chan int {
ch := make(chan int)
go func() {
for i := 1; ; i++ {
ch <- i
}
}()
return ch
}
func foo() {
for n := range pump() {
println(n)
if n >= 10 {
break
}
}
}
func main() {
for i := 0; i < 10; i++ {
foo()
}
for {
}
}
> When using goroutines and channels as generators, a colleague asked
> the innocuous question: how do you clean up goroutines you no longer
> need? I wrote the toy program below, which captures the essence of
> the issue. Each goroutine emits an unbounded sequence of int's on a
> channel. Function foo() consumes some of the values, then exits. The
> program below ended up "leaking" 10 goroutines, even though there is
> no possibility that they could ever run again.
>
> 1. Is it reasonable to expect the runtime to garbage collect these
> goroutines, considering there are no other references to the channel
> they're blocked on?
Yes, it would be reasonable but the run time doesn't do that yet, which we consider a TODO.
> 2. Is there a clean way to exit a goroutine when it is no longer
> needed?
Just return from it. Its resources will be freed by the garbage collector.
-rob