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

How to Gracefully Terminate a Golang Ticker Goroutine?

Mary-Kate Olsen
Release: 2024-11-08 16:42:02
Original
730 people have browsed it

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)
}
Copy after login

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)
}
Copy after login

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!

source:php.cn
Statement of this Website
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
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template