在 Golang 中,Ticker Channel 通常用於建立定期發生的事件。但是,了解 Stop() 的行為方式以確保正確的通道處理非常重要。
考慮以下程式碼片段:
ticker := time.NewTicker(1 * time.Second) go func() { for _ = range ticker.C { log.Println("tick") } log.Println("stopped") }() time.Sleep(3 * time.Second) log.Println("stopping ticker") ticker.Stop() time.Sleep(3 * time.Second)
當呼叫ticker.Stop() 時,股票碼暫停,但通道不會自動關閉。這意味著 goroutine 將暫停但不會終止。執行上述程式碼會產生以下輸出:
2013/07/22 14:26:53 tick 2013/07/22 14:26:54 tick 2013/07/22 14:26:55 tick 2013/07/22 14:26:55 stopping ticker
因此,goroutine 保持阻塞狀態,等待進一步的程式碼事件。
要解決此問題,可以使用第二個通道來傳達停止對股票代碼 goroutine 的請求。以下是一個範例:
package main import ( "log" "sync" "time" ) type Ticker struct { sync.Mutex ticker *time.Ticker stop chan struct{} } func (t *Ticker) Start(d time.Duration) { t.Lock() defer t.Unlock() if t.ticker != nil { t.ticker.Stop() } t.ticker = time.NewTicker(d) t.stop = make(chan struct{}) go func() { for { select { case <-t.ticker.C: log.Println("tick") case <-t.stop: return } } }() } func (t *Ticker) Stop() { t.Lock() defer t.Unlock() if t.stop != nil { close(t.stop) t.ticker.Stop() } } func main() { t := Ticker{} t.Start(1 * time.Second) time.Sleep(3 * time.Second) log.Println("stopping ticker") t.Stop() time.Sleep(3 * time.Second) }
透過使用單獨的停止通道,我們可以確保在呼叫 Ticker.Stop() 方法時正確終止 Ticker Goroutine。
以上是Ticker.Stop() 在 Golang 中的行為如何,我們如何確保 Ticker Goroutines 優雅退出?的詳細內容。更多資訊請關注PHP中文網其他相關文章!