# 定時器
在time包中有兩個函數可以幫助我們初始化time.Timer
### time.Newtimer函數
初始化一個到期時間據此時的間隔為3小時30分的定時器
~~~
t := time.Newtimer(3*time.Hour + 30*time.Minute)
~~~
注意,這里的變量t是*time.NewTimer類型的,這個指針類型的方法集合包含兩個方法
- Rest
- 用于重置定時器
- 該方法返回一個bool類型的值
- Stop
- 用來停止定時器
- 該方法返回一個bool類型的值,如果返回false,說明該定時器在之前已經到期或者已經被停止了,反之返回true。
通過定時器的字段C,我們可以及時得知定時器到期的這個事件來臨,C是一個chan time.Time類型的緩沖通道,一旦觸及到期時間,定時器就會向自己的C字段發送一個time.Time類型的元素值
示例一:一個簡單定時器
~~~
package main
import (
"fmt"
"time"
)
func main(){
//初始化定時器
t := time.NewTimer(2 * time.Second)
//當前時間
now := time.Now()
fmt.Printf("Now time : %v.\n", now)
expire := <- t.C
fmt.Printf("Expiration time: %v.\n", expire)
}
~~~
> Now time : 2015-10-31 01:19:07.210771347 +0800 CST.
Expiration time: 2015-10-31 01:19:09.215489592 +0800 CST.
示例二:我們在改造下之前的那個簡單超時操作
~~~
package main
import (
"fmt"
"time"
)
func main(){
//初始化通道
ch11 := make(chan int, 1000)
sign := make(chan byte, 1)
//給ch11通道寫入數據
for i := 0; i < 1000; i++ {
ch11 <- i
}
//單獨起一個Goroutine執行select
go func(){
var e int
ok := true
//首先聲明一個*time.Timer類型的值,然后在相關case之后聲明的匿名函數中盡可能的復用它
var timer *time.Timer
for{
select {
case e = <- ch11:
fmt.Printf("ch11 -> %d\n",e)
case <- func() <-chan time.Time {
if timer == nil{
//初始化到期時間據此間隔1ms的定時器
timer = time.NewTimer(time.Millisecond)
}else {
//復用,通過Reset方法重置定時器
timer.Reset(time.Millisecond)
}
//得知定時器到期事件來臨時,返回結果
return timer.C
}():
fmt.Println("Timeout.")
ok = false
break
}
//終止for循環
if !ok {
sign <- 0
break
}
}
}()
//慣用手法,讀取sign通道數據,為了等待select的Goroutine執行。
<- sign
}
~~~
### time.After函數
- time.After函數, 表示多少時間之后,但是在取出channel內容之前不阻塞,后續程序可以繼續執行
- 鑒于After特性,其通常用來處理程序超時問題
~~~
package main
import (
"fmt"
"time"
)
func main(){
ch1 := make(chan int, 1)
ch2 := make(chan int, 1)
select {
case e1 := <-ch1:
//如果ch1通道成功讀取數據,則執行該case處理語句
fmt.Printf("1th case is selected. e1=%v",e1)
case e2 := <-ch2:
//如果ch2通道成功讀取數據,則執行該case處理語句
fmt.Printf("2th case is selected. e2=%v",e2)
case <- time.After(2 * time.Second):
fmt.Println("Timed out")
}
}
~~~
> Timed out
- time.Sleep函數,表示休眠多少時間,休眠時處于阻塞狀態,后續程序無法執行.
### time.Afterfunc函數
示例三:自定義定時器
~~~
package main
import (
"fmt"
"time"
)
func main(){
var t *time.Timer
f := func(){
fmt.Printf("Expiration time : %v.\n", time.Now())
fmt.Printf("C`s len: %d\n", len(t.C))
}
t = time.AfterFunc(1*time.Second, f)
//讓當前Goroutine 睡眠2s,確保大于內容的完整
//這樣做原因是,time.AfterFunc的調用不會被阻塞。它會以一部的方式在到期事件來臨執行我們自定義函數f。
time.Sleep(2 * time.Second)
}
~~~
> Expiration time : 2015-10-31 01:04:42.579988801 +0800 CST.
C`s len: 0
第二行打印內容說明:定時器的字段C并沒有緩沖任何元素值。這也說明了,在給定了自定義函數后,默認的處理方法(向C發送代表絕對到期時間的元素值)就不會被執行了。
# 斷續器
結構體類型time.Ticker表示了斷續器的靜態結構。
就是周期性的傳達到期時間的裝置。這種裝置的行為方式與僅有秒針的鐘表有些類似,只不過間隔時間可以不是1s。
初始化一個斷續器
~~~
var ticker *timeTicker = time.NewTicker(time.Second)
~~~
### 示例一:使用時間控制停止ticke
~~~
package main
import (
"fmt"
"time"
)
func main(){
//初始化斷續器,間隔2s
var ticker *time.Ticker = time.NewTicker(1 * time.Second)
go func() {
for t := range ticker.C {
fmt.Println("Tick at", t)
}
}()
time.Sleep(time.Second * 5) //阻塞,則執行次數為sleep的休眠時間/ticker的時間
ticker.Stop()
fmt.Println("Ticker stopped")
}
~~~
> Tick at 2015-10-31 01:29:34.41859284 +0800 CST
Tick at 2015-10-31 01:29:35.420131668 +0800 CST
Tick at 2015-10-31 01:29:36.420565647 +0800 CST
Tick at 2015-10-31 01:29:37.421038416 +0800 CST
Tick at 2015-10-31 01:29:38.41944582 +0800 CST
Ticker stopped
### 示例二:使用channel控制停止ticker
~~~
package main
import (
"fmt"
"time"
)
func main(){
//初始化斷續器,間隔2s
var ticker *time.Ticker = time.NewTicker(100 * time.Millisecond)
//num為指定的執行次數
num := 2
c := make(chan int, num)
go func() {
for t := range ticker.C {
c <- 1
fmt.Println("Tick at", t)
}
}()
time.Sleep(time.Millisecond * 1500)
ticker.Stop()
fmt.Println("Ticker stopped")
}
~~~
- 前言
- golang學習(一)之安裝
- Go語言學習二:Go基礎(變量、常量、數值類型、字符串、錯誤類型)
- Go語言學習三:Go基礎(iota,array,slice,map,make,new)
- Go語言學習四:struct類型
- Ubuntu 14.04/CentOS 6.5中安裝GO LANG(GO語言)
- Mac OS 安裝golang
- Mac install Thrift
- Thrift RPC 使用指南實戰(附golang&amp;PHP代碼)
- golang net/http包使用
- 冒泡排序Bubble sort-golang
- 快速排序Quick sort - golang
- Go語言學習:Channel是什么?
- Golang的select/非緩沖的Channel實例詳解
- Golang time包的定時器/斷續器
- Golang同步:鎖的使用案例詳解
- Golang同步:條件變量和鎖組合使用
- Golang同步:原子操作使用
- Golang之bytes.buffer
- Golang之字符串格式化
- Golang之反射reflect包
- Go語言配置文件解析器,類似于Windows下的INI文件.