Home >Backend Development >Golang >How to Gracefully Terminate a Golang Ticker Goroutine?

How to Gracefully Terminate a Golang Ticker Goroutine?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-08 16:42:02716browse

How to Gracefully Terminate a Golang Ticker Goroutine?

Ticker Stop Behavior in Golang

When using Golang's ticker package, it's essential to understand the behavior of Stop() and the impact it has on the associated channel. While calling Stop() effectively halts ticker emissions, it doesn't close the channel.

Consider the example:

package main

import (
    "time"
    "log"
)

func main() {
    ticker := time.NewTicker(1 * time.Second)
    go func(){
        for _ = range ticker.C {
            log.Println("tick")
        }
        log.Println("stopped")
    }()
    time.Sleep(3 * time.Second)
    log.Println("stopping ticker")
    ticker.Stop()
    time.Sleep(3 * time.Second)
}

This code demonstrates the unexpected behavior. The ticker channel is stopped using ticker.Stop(), but the corresponding goroutine remains active. This raises concerns about whether the goroutine's continued existence is undesirable and the best approach to handle such situations.

Using a Second Channel for Stopping

One effective solution is to introduce a second channel, specifically for signaling the ticker to stop.

package main

import (
    "log"
    "time"
)

// Every runs the provided function periodically, allowing the function to control when to stop.
func Every(duration time.Duration, work func(time.Time) bool) chan bool {
    ticker := time.NewTicker(duration)
    stop := make(chan bool, 1) // Channel for signaling stop

    go func() {
        defer log.Println("ticker stopped")
        for {
            select {
            case time := <-ticker.C:
                if !work(time) { // Function decides to stop
                    stop <- true
                }
            case <-stop: // Signal to stop has been received
                return
            }
        }
    }()

    return stop
}

func main() {
    stop := Every(1*time.Second, func(time.Time) bool {
        log.Println("tick")
        return true
    })

    time.Sleep(3 * time.Second)
    log.Println("stopping ticker")
    stop <- true // Send the stop signal on the stop channel
    time.Sleep(3 * time.Second)
}

In this modified code, Every() function takes both a duration and a function that returns a boolean indicating whether to continue. The stop channel is used to communicate the stop signal to the ticker goroutine, ensuring its graceful termination.

The above is the detailed content of How to Gracefully Terminate a Golang Ticker Goroutine?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn