Reputation: 37
Following this post about go-routines leaking, https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sender.html, i tried to solve my leaking code. But adding a buffer to the channel it did not do the trick.
My code
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
fmt.Println(runtime.NumGoroutine())
leaking()
time.Sleep(5)
fmt.Println(runtime.NumGoroutine())
}
func leaking() {
errChang := make(chan int, 1)
go func() {
xx := return666()
errChang <- xx
}()
fmt.Println("hola")
return
fmt.Println(<-errChang)
}
func return666() int {
time.Sleep(time.Second * 1)
return 6
}
My initial code did not use a buffer, leading to the go-routine in the leaking function, .. to leak. Following the post i expected that by adding a buffer to the channel, it would have avoided leaking.
Upvotes: 1
Views: 1184
Reputation: 488193
Here, in the Go Playground, is your original code with a few slight modifications:
time.Sleep(5)
which becomes time.Sleep(time.Second)
;return
is removed because it becomes unnecessary;fmt.Println
is commented out, because with both the return
and the uncommented fmt.Println
, go vet
complains about the unreachable fmt.Println
;errChang
is changed to unbuffered.When run, its output is:
1
hola
2
(with a small delay before the 2
), showing that indeed, the anonymous goroutine you started in function leaking
is still running.
If we uncomment the commented-out fmt.Println
, the output is:
1
hola
6
1
(with the same slight delay before the final 1
) because we now wait for (and then print) the value computed in return666
and sent over channel errChang
.
If we keep the commented-out fmt.Println
commented out and make the channel buffered, the output becomes:
1
hola
1
as the anonymous goroutine is now able to push its value (6) into the channel.
The channel itself would be garbage collected, along with the single value stored inside it, as there are no remaining references to the channel at this point. Note, however, that simply making the channel buffered is not always sufficient. If we send two values down the channel, the program returns to printing:
1
hola
2
as the anonymous goroutine succeeds in putting 6
into the channel but then blocks trying to put 42
in as well.
Upvotes: 1