Go 1.23中Timer無buffer的實現方式竟是這樣!
在 Go 1.23 中,Timer 的實現通常是通過 time 包提供的 time.Timer 類型來實現的。Timer 是一個用于在指定時間后觸發一次事件的計時器。Timer 的實現并不依賴于緩沖區,而是通過 Go 的調度器和通道機制來實現的。
Timer 的基本實現
Timer 的核心是一個 time.Timer 結構體,它包含一個 time.Timer.C 通道,當計時器到期時,當前時間會被發送到這個通道。
以下是一個簡單的 Timer 實現示例:
package main
import (
"fmt"
"time"
)
func main() {
// 創建一個 Timer,設置 2 秒后觸發
timer := time.NewTimer(2 * time.Second)
// 等待 Timer 觸發
<-timer.C
fmt.Println("Timer expired")
// 如果你想要停止 Timer,可以使用 Stop() 方法
// timer.Stop()
}
無緩沖區的實現
Timer 的實現并不依賴于緩沖區,而是通過 Go 的通道機制來實現的。Timer.C 是一個無緩沖的通道,當計時器到期時,當前時間會被發送到這個通道。由于通道是無緩沖的,發送操作會阻塞,直到有接收者準備好接收數據。
自定義無緩沖 Timer 實現
如果你想自己實現一個無緩沖的 Timer,可以使用 time.After 函數,它返回一個通道,當指定的時間到達時,通道會接收到一個時間值。
package main
import (
"fmt"
"time"
)
func main() {
// 使用 time.After 創建一個無緩沖的 Timer
timerCh := time.After(2 * time.Second)
// 等待 Timer 觸發
<-timerCh
fmt.Println("Timer expired")
}
更復雜的 Timer 實現
如果你需要更復雜的 Timer 實現,比如可以重置或停止的 Timer,可以參考以下代碼:
package main
import (
"fmt"
"time"
)
type MyTimer struct {
duration time.Duration
timer *time.Timer
resetCh chan time.Duration
stopCh chan struct{}
}
func NewMyTimer(duration time.Duration) *MyTimer {
t := &MyTimer{
duration: duration,
resetCh: make(chan time.Duration),
stopCh: make(chan struct{}),
}
t.timer = time.NewTimer(duration)
go t.run()
return t
}
func (t *MyTimer) run() {
for {
select {
case <-t.timer.C:
fmt.Println("Timer expired")
return
case newDuration := <-t.resetCh:
if !t.timer.Stop() {
<-t.timer.C
}
t.timer.Reset(newDuration)
case <-t.stopCh:
if !t.timer.Stop() {
<-t.timer.C
}
return
}
}
}
func (t *MyTimer) Reset(duration time.Duration) {
t.resetCh <- duration
}
func (t *MyTimer) Stop() {
t.stopCh <- struct{}{}
}
func main() {
timer := NewMyTimer(2 * time.Second)
time.Sleep(1 * time.Second)
timer.Reset(3 * time.Second)
time.Sleep(2 * time.Second)
timer.Stop()
fmt.Println("Timer stopped")
}
在這個示例中,MyTimer 是一個自定義的 Timer 實現,它支持重置和停止操作。MyTimer 使用 time.Timer 作為底層實現,并通過通道來接收重置和停止的信號。
總結
Go 中的 Timer 實現依賴于無緩沖的通道和 Go 的調度器。你可以使用 time.Timer 或 time.After 來創建簡單的 Timer,或者通過自定義結構體來實現更復雜的 Timer 功能。