首頁  >  文章  >  後端開發  >  如何優雅地終止 Golang Ticker Goroutine?

如何優雅地終止 Golang Ticker Goroutine?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-11-08 16:42:02641瀏覽

How to Gracefully Terminate a Golang Ticker Goroutine?

Golang 中的Ticker Stop 行為

使用Golang 的Ticker 包時,必須了解Stop() 的行為及其影響在相關頻道上。雖然呼叫 Stop() 有效地停止了股票發射,但它不會關閉通道。

考慮範例:

package main

import (
    "time"
    "log"
)

func main() {
    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 保持活動狀態。這引起了人們的擔憂:goroutine 的繼續存在是否是不可取的,以及處理這種情況的最佳方法。

使用第二個通道來停止

一個有效的解決方案是引入第二個通道,專門用於發出停止股票訊號的訊號。

package main

import (
    "log"
    "time"
)

// Every runs the provided function periodically, allowing the function to control when to stop.
func Every(duration time.Duration, work func(time.Time) bool) chan bool {
    ticker := time.NewTicker(duration)
    stop := make(chan bool, 1) // Channel for signaling stop

    go func() {
        defer log.Println("ticker stopped")
        for {
            select {
            case time := <-ticker.C:
                if !work(time) { // Function decides to stop
                    stop <- true
                }
            case <-stop: // Signal to stop has been received
                return
            }
        }
    }()

    return stop
}

func main() {
    stop := Every(1*time.Second, func(time.Time) bool {
        log.Println("tick")
        return true
    })

    time.Sleep(3 * time.Second)
    log.Println("stopping ticker")
    stop <- true // Send the stop signal on the stop channel
    time.Sleep(3 * time.Second)
}

在此修改後的程式碼中, Every() 函數接受持續時間和傳回指示是否繼續的布林值的函數。停止通道用於向ticker goroutine傳達停止信號,確保其優雅終止。

以上是如何優雅地終止 Golang Ticker Goroutine?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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