在 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中文网其他相关文章!