首頁 >後端開發 >Golang >Ticker.Stop() 在 Golang 中的行為如何,我們如何確保 Ticker Goroutines 優雅退出?

Ticker.Stop() 在 Golang 中的行為如何,我們如何確保 Ticker Goroutines 優雅退出?

Linda Hamilton
Linda Hamilton原創
2024-11-09 04:38:02598瀏覽

How does Ticker.Stop() behave in Golang, and how can we ensure graceful exits for ticker goroutines?

Golang 中的 Ticker Stop 行為:處理優雅退出

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

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn