定時器Timer
Timer是利用channel來實現定時的效果,他會在給定的時候向timer.C(是個channel)中輸入一個時間,在此之前timer.C會阻塞。
package main
import (
"fmt"
"time"
)
func main() {
timer := time.NewTimer(2 * time.Second) //定時2秒,向timer.C中寫入一個時間
fmt.Printf("t1: %v\n", time.Now())
t2 := <-timer.C //沒有消息會阻塞
fmt.Printf("t2: %v\n", t2)
//如果只想延時也可以用sleep
time.Sleep(2 * time.Second)
fmt.Printf("t3: %v\n", time.Now())
//簡寫
<-time.After(2 * time.Second)
fmt.Printf("t4: %v\n", time.Now())
}
定時器是可以重置和停止的
fmt.Println("t0 = ",time.Now())
timer := time.NewTimer(3 * time.Second)
t1 := timer.Reset(1 * time.Second) //重新設置爲1s
fmt.Println("t1 = ", t1)
<-timer.C
fmt.Println("t2 = ",time.Now()) //和t1只隔1秒
停止:
timer2.Stop() //停止定時器
Ticker
Ticker等於是個死循環的Timer,每隔一段時間寫入一次
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(1 * time.Second)
i := 0
for {
<-ticker.C
i++
fmt.Println("i = ", i)
if i == 5 {
ticker.Stop()
break
}
}
}
select
select可以監聽channel上的數據流動。
select {
case <-chan1:
// 如果chan1成功讀到數據,則進行該case處理語句
case chan2 <- 1:
// 如果成功向chan2寫入數據,則進行該case處理語句
default:
// 如果上面都沒有成功,則進入default處理流程
}
可以用來寫觸發器和超時判斷。
//fibonacci 1 1 2 3 5 8
package main
import (
"fmt"
)
//生成斐波拉契數列
func fibonacci(consumers chan<- int, quit <-chan bool) {
x, y := 1, 1
//死循環,由於channel沒有緩衝區,所以沒有消費者讀取就會一直堵塞
for {
//監聽channel數據的流動
select {
case consumers <- x: //寫入成功就處理
x, y = y, x+y
fmt.Println("x = ", x)
fmt.Println("y = ", y)
case flag := <-quit:
fmt.Println("要停止的標誌 = ", flag)
return
}
}
}
func main() {
consumers := make(chan int) //注意是沒有緩衝區的
quit := make(chan bool) //程序是否結束
//消費者,從channel讀取內容
//新建協程
go func() {
for i := 0; i < 16; i++ {
num := <-consumers
fmt.Println(num)
}
//可以停止
quit <- true
}() //別忘了()
//生產者,產生數字,寫入channel
fibonacci(consumers, quit)
}
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
quit := make(chan bool)
//新開一個協程
go func() {
for {
select {
case num := <-ch:
fmt.Println("num = ", num)
case <-time.After(3 * time.Second):
fmt.Println("超時")
quit <- true
}
}
}() //別忘了()
for i := 0; i < 5; i++ {
ch <- i
time.Sleep(time.Second)
}
//阻塞3秒則退出
<-quit
fmt.Println("程序結束")
}