Maison >développement back-end >Golang >Comment terminer gracieusement une goroutine Golang Ticker ?

Comment terminer gracieusement une goroutine Golang Ticker ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-08 16:42:02716parcourir

How to Gracefully Terminate a Golang Ticker Goroutine?

Comportement du ticker Stop dans Golang

Lors de l'utilisation du package ticker de Golang, il est essentiel de comprendre le comportement de Stop() et son impact sur le canal associé. Bien que l'appel de Stop() arrête efficacement les émissions de tickers, il ne ferme pas la chaîne.

Prenons l'exemple :

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)
}

Ce code démontre le comportement inattendu. Le canal ticker est arrêté à l'aide de ticker.Stop(), mais la goroutine correspondante reste active. Cela soulève des inquiétudes quant à savoir si l'existence continue de la goroutine est indésirable et quelle est la meilleure approche pour gérer de telles situations.

Utiliser un deuxième canal pour arrêter

Une solution efficace consiste à introduire un deuxième canal, spécifiquement pour signaler l'arrêt du ticker.

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)
}

Dans ce code modifié, la fonction Every() prend à la fois une durée et une fonction qui renvoie un booléen indiquant s'il faut continuer. Le canal d'arrêt est utilisé pour communiquer le signal d'arrêt au ticker goroutine, assurant sa terminaison gracieuse.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn