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