Go語言學習筆記20.定時器、超時

定時器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("程序結束")

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章