I'm writing some golang concurrency codes with goroutines and channels, suspecting that my code may cause goroutine leaks. My situation is similar to the following code, or you can open this go playground link.
func main() {
numCount := 3
numChan := make(chan int)
for i := 0; i < numCount; i++ {
go func(num int) {
fmt.Printf("Adding num: %d to chan
", num)
numChan <- num
fmt.Printf("Adding num: %d to chan Done
", num)
}(i)
}
time.Sleep(time.Second)
panic("Goroutine Resource Leak Test")
}
In my opinion, when the main goroutine returns, three goroutines are blocked sending to the unbuffered channel and there will be goroutine leak. This post goroutine leak with buffered channel in Go also suggests that So only if the channel was unbuffered the leak would occur
.
The Go Programming Language suggests that:
There’s a handy trick we can use during testing: if instead of returning from main in the event of cancellation, we execute a call to panic, then the runtime will dump the stack of every goroutine in the program. If the main goroutine is the only one left, then it has cleaned up after itself. But if other goroutines remain, they may not have been properly canceled, or perhaps they have been canceled but the cancellation takes time; a little investigation may be worthwhile. The panic dump often contains sufficient information to distinguish these cases.
Therefore, I added panic("Goroutine Resource Leak Test")
to the end of the main function to verify my assumption. However, the panic dump only contains main goroutine, that is, there is no resource leak.
Adding num: 0 to chan
Adding num: 1 to chan
Adding num: 2 to chan
panic: Goroutine Resource Leak Test
goroutine 1 [running]:
main.main()
/tmp/sandbox011109649/prog.go:21 +0xc0
Can someone help explain
- why there is no goroutine leak, or
- how should I get the correct panic dump if there is leak
Any suggestion will be appreciated, thanks in advance!