Heim  >  Artikel  >  Backend-Entwicklung  >  Wie beendet man eine Golang-Ticker-Goroutine ordnungsgemäß?

Wie beendet man eine Golang-Ticker-Goroutine ordnungsgemäß?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-08 16:42:02641Durchsuche

How to Gracefully Terminate a Golang Ticker Goroutine?

Ticker-Stopp-Verhalten in Golang

Bei der Verwendung des Tickerpakets von Golang ist es wichtig, das Verhalten von Stop() und die Auswirkungen, die es hat, zu verstehen auf dem zugehörigen Kanal. Der Aufruf von Stop() stoppt zwar effektiv die Tickeremissionen, schließt aber nicht den Kanal.

Betrachten Sie das Beispiel:

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)
}

Dieser Code demonstriert das unerwartete Verhalten. Der Tickerkanal wird mit ticker.Stop() gestoppt, die entsprechende Goroutine bleibt jedoch aktiv. Dies wirft Bedenken auf, ob das Fortbestehen der Goroutine unerwünscht ist und der beste Ansatz für den Umgang mit solchen Situationen ist.

Verwendung eines zweiten Kanals zum Stoppen

Eine wirksame Lösung ist die Einführung ein zweiter Kanal, speziell um dem Ticker zu signalisieren, dass er anhalten soll.

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)
}

In diesem modifizierten Code benötigt die Every()-Funktion sowohl eine Dauer als auch Eine Funktion, die einen booleschen Wert zurückgibt, der angibt, ob fortgefahren werden soll. Der Stoppkanal wird verwendet, um das Stoppsignal an die Ticker-Goroutine zu übermitteln und so dessen ordnungsgemäße Beendigung sicherzustellen.

Das obige ist der detaillierte Inhalt vonWie beendet man eine Golang-Ticker-Goroutine ordnungsgemäß?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn