Tickers
Un tickerè simile ad un timer, in quanto allo scatto invia un elemento al suo channel C
.
Ma un ticker continua all'infinito a scattare a intervalli regolari.
E' una differenza simile a quella di at
e cron
in Linux.
Un ticker si crea in memoria dinamica con la funzione NewTicker
.
Un ticker è fermabile con la funzione Stop
, ma non è più ristartabile.
L'elemento posto sul channel C
è un timestamp.
Esempio
(330tickers.go):
package main
import "time"
import "fmt"
func main() {
// Un ticker ha un channel che riceve un elemento
// a intervalli regolari
fmt.Println("main: ticker set every 500 ms")
ticker := time.NewTicker(time.Millisecond * 500)
// Goroutine che legge il ticker se pieno
// oppure conta i secondi
go func() {
i := 0
for {
select {
case t := <-ticker.C:
fmt.Println("go: tick at", t)
case <- time.After(time.Second):
i++
fmt.Printf("go: still here after %d sec\n", i)
}
}
}()
// I ticker si possono fermare come i timer
fmt.Println("main: sleeping for 5600 ms")
time.Sleep(time.Millisecond * 5600)
ticker.Stop()
fmt.Println("main: ticker stopped")
// Fermare un ticker non termina i thread che lo ascoltano
// Un ticker non si può risettare
fmt.Println("main: waiting 5 seconds before exiting")
<-time.After(5 * time.Second)
fmt.Println("main: exiting now")
}
Anche qui allo stop del ticker tutte le routine che lo leggono continuano ad attendere se non sono informate.
Due goroutine in lettura
Se due goroutine leggono dallo stesso ticker, la prima che arriva legge, l'altra no e perde il turno.
Questo è dimostrato dal programma:
(331-tickers-two.go):
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(time.Second)
go func() {
i := 0
for {
select {
case t := <-ticker.C:
fmt.Println("go1: tick at", t)
case <-time.After(time.Millisecond * 500):
i++
fmt.Printf("go1: still here after %d millisec\n", i*500)
}
}
}()
go func() {
i := 0
for {
select {
case t := <-ticker.C:
fmt.Println("go2: tick at", t)
case <-time.After(time.Millisecond * 800):
i++
fmt.Printf("go2: still here after %d millisec\n", i*800)
}
}
}()
<-time.After(10 * time.Second)
fmt.Println("main: exiting now")
}