introduction
Timer
可以讓用戶自定義超時的邏輯- 尤其是在應對
select
處理多個channel
的超時、單channel
讀寫的超時等情形, - 為一次性的時間觸發事件,其與
Ticker
不同
- 尤其是在應對
Ticker
是按一定時間間隔持續觸發時間事件- 設置超時時間(timeout),避免阻塞時間過長
- 定時器(
Ticker
)位於time
包中,使用NewTicker()
方法生成定時器
生成定時器(Ticker
)
1 | package main |
timer.C
本身為一個channel,其後端有一個goroutine,每隔一段NewTicker()
方法設置的時間參數,會往裡面寫入時間- 上述利用
range()
方法將數據取出
result
1 | hello 2018-05-19 18:18:47.193000586 +0800 CST m=+1.004599317 |
- 因為每隔一秒goroutine才會往
timer.C
管道扔數據,因此主線程也是每一秒才能從管道中取出數據
一次性定時器
- 搭配
select
一起使用,仍是用作設置timeout time.After(Time)
的參數為一時間- 相當於
time.NewTimer(d).C
- 為一 只讀channel 類型
- 相當於
其它創建方式
1
2t := time.NewTimer(d)
t := time.AfterFunc(d,f)- 定時時間:
d
- 觸發後執行的動作:
f
- 時間channel:
t
- 定時時間:
example 1
1 | package main |
result
1 | i value 0 in Chan 1 |
tips
- 較不推薦使用此方法作為超時控制,因為
time.After()
並未關閉, - 在for無限循環中可以看到,會創建越來越多的管道造成內存overflow
example 2
- 使用time.NewTimer()作為一次性計時器
1 | package main |
example 3
- 使用time.NewTicker()作為一次性的計時器
1 | package main |
result
1 | i value 0 in Chan 1 |
- 第一次select已經關閉timer,但管道未滿,
- 第四次select後,timer已關閉,再次使用發生panic
tips
推薦使用第二種方式當作一次性的定時器