I have this code that I deliberately wrote to cause a deadlock and a subsequent panic throw:
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Start:", time.Now())
channel1 := make(chan string, 2)
channel1 <- "Cat"
channel1 <- "Dog"
limiter := time.NewTicker(time.Millisecond * 500)
for channel1Item := range channel1 {
<-limiter.C
fmt.Println(channel1Item)
}
fmt.Println("End:", time.Now())
}
In a way, a deadlock does happen and the code just hangs indefinitely, however, it does not throw a panic. If I remove the limiter (ticker), it then does. Why does the ticker prevent the panic from being thrown?
I am currently learning Go and I accidentally stumbled into this example when changing random bits to satiate my curiosity. The strange behavior (of a panic not being throw) happened after I decided not to close the channel to see what would happen.
I know ranging over an open channel that is not being fed generally throws a panic, but it seems that having a ticker inside the loop interrupts the panic throwing behavior.
Because the judgment in GO is that when a goroutine attempts to send a worthy message on a closed channel, it will trigger panic.
In your code, you did not close channel1, so the loop will wait indefinitely for channel1 to accept the value. <- limiter. C will periodically send values to the channel So channel1 won't rule out panic, loops with limiters will hang Even if he doesn't have any new value
I hope it can be helpful to you