Maison > développement back-end > Golang > le corps du texte

Comment Ticker.Stop() se comporte-t-il dans Golang et comment pouvons-nous garantir des sorties gracieuses pour les goroutines de ticker ?

Linda Hamilton
Libérer: 2024-11-09 04:38:02
original
521 Les gens l'ont consulté

How does Ticker.Stop() behave in Golang, and how can we ensure graceful exits for ticker goroutines?

Comportement d'arrêt du téléscripteur dans Golang : gestion des sorties gracieuses

Dans Golang, un canal de téléscripteur est couramment utilisé pour créer un événement se produisant régulièrement. Cependant, il est important de comprendre comment Stop() se comporte pour garantir une gestion correcte des canaux.

Considérez l'extrait de code suivant :

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)
Copier après la connexion

Lorsque ticker.Stop() est appelé, le ticker est est en pause, mais la chaîne ne se ferme pas automatiquement. Cela signifie que la goroutine fera une pause mais ne se terminera pas. L'exécution du code ci-dessus produit le résultat suivant :

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
Copier après la connexion

Par conséquent, la goroutine reste bloquée en attendant d'autres événements ticker.

Pour résoudre ce problème, on peut utiliser un deuxième canal pour communiquer le demande d'arrêt au ticker goroutine. Voici un exemple :

package main

import (
    "log"
    "sync"
    "time"
)

type Ticker struct {
    sync.Mutex
    ticker *time.Ticker
    stop   chan struct{}
}

func (t *Ticker) Start(d time.Duration) {
    t.Lock()
    defer t.Unlock()

    if t.ticker != nil {
        t.ticker.Stop()
    }

    t.ticker = time.NewTicker(d)
    t.stop = make(chan struct{})

    go func() {
        for {
            select {
            case <-t.ticker.C:
                log.Println("tick")
            case <-t.stop:
                return
            }
        }
    }()
}

func (t *Ticker) Stop() {
    t.Lock()
    defer t.Unlock()

    if t.stop != nil {
        close(t.stop)
        t.ticker.Stop()
    }
}

func main() {
    t := Ticker{}
    t.Start(1 * time.Second)

    time.Sleep(3 * time.Second)
    log.Println("stopping ticker")
    t.Stop()

    time.Sleep(3 * time.Second)
}
Copier après la connexion

En utilisant un canal d'arrêt distinct, nous pouvons garantir la fin correcte de la goroutine du ticker lorsque la méthode Ticker.Stop() est appelée.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal