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 :
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!