Ticker Channel Behavior in Golang
If you iterate over a ticker channel and call Stop(), the channel will pause but not close. This can lead to goroutines remaining active indefinitely.
Case Example:
Consider the following code snippet:
package main import ( "fmt" "time" ) func main() { ticker := time.NewTicker(1 * time.Second) go func() { for _ = range ticker.C { fmt.Println("tick") } }() time.Sleep(3 * time.Second) fmt.Println("stopping ticker") ticker.Stop() time.Sleep(3 * time.Second) }
Output:
2013/07/22 14:26:53 tick 2013/07/22 14:26:54 tick 2013/07/22 14:26:55 tick 2013/07/22 14:26:55 stopping ticker
As you can see, despite stopping the ticker, the goroutine continues to iterate indefinitely because the channel is not closed.
Solution:
One way to ensure the goroutine terminates is to use a second channel as follows:
package main import ( "fmt" "log" "time" ) // Run the function every tick // Return false from the func to stop the ticker func Every(duration time.Duration, work func(time.Time) bool) chan bool { ticker := time.NewTicker(duration) stop := make(chan bool, 1) go func() { defer log.Println("ticker stopped") for { select { case time := <-ticker.C: if !work(time) { stop <- true } case <-stop: return } } }() return stop } func main() { stop := Every(1*time.Second, func(time.Time) bool { fmt.Println("tick") return true }) time.Sleep(3 * time.Second) fmt.Println("stopping ticker") stop <- true time.Sleep(3 * time.Second) }
In this code:
The above is the detailed content of How to Properly Terminate a Goroutine When Using a Ticker Channel in Golang?. For more information, please follow other related articles on the PHP Chinese website!