Maison  >  Article  >  développement back-end  >  Comment terminer correctement une Goroutine lors de l'utilisation d'un canal ticker dans Golang ?

Comment terminer correctement une Goroutine lors de l'utilisation d'un canal ticker dans Golang ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-07 19:16:02422parcourir

How to Properly Terminate a Goroutine When Using a Ticker Channel in Golang?

Comportement du canal ticker dans Golang

Si vous parcourez un canal ticker et appelez Stop(), le canal se mettra en pause mais ne se fermera pas. Cela peut conduire les goroutines à rester actives indéfiniment.

Exemple de cas :

Considérez l'extrait de code suivant :

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

Sortie :

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

Comme vous pouvez le constater, malgré l'arrêt du ticker, la goroutine continue d'itérer indéfiniment car le canal n'est pas fermé.

Solution :

Une façon de garantir que la goroutine se termine est d'utiliser un deuxième canal comme suit :

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

Dans ce code :

  • La fonction Every crée deux canaux : un canal ticker et un canal d'arrêt.
  • La goroutine parcourt les deux canaux.
  • Si la fonction de travail renvoie false, le canal d'arrêt est notifié, provoquant la sortie de la goroutine.
  • Lorsque Stop() est appelé, il envoie un message au canal d'arrêt, qui met fin à la goroutine.

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