Heim  >  Artikel  >  Backend-Entwicklung  >  Wie beendet man eine Goroutine ordnungsgemäß, wenn man einen Ticker-Kanal in Golang verwendet?

Wie beendet man eine Goroutine ordnungsgemäß, wenn man einen Ticker-Kanal in Golang verwendet?

Patricia Arquette
Patricia ArquetteOriginal
2024-11-07 19:16:02422Durchsuche

How to Properly Terminate a Goroutine When Using a Ticker Channel in Golang?

Verhalten des Tickerkanals in Golang

Wenn Sie über einen Tickerkanal iterieren und Stop() aufrufen, wird der Kanal angehalten, aber nicht geschlossen. Dies kann dazu führen, dass Goroutinen auf unbestimmte Zeit aktiv bleiben.

Fallbeispiel:

Betrachten Sie den folgenden Codeausschnitt:

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(1 * time.Second)
    go func() {
        for _ = range ticker.C {
            fmt.Println("tick")
        }
    }()
    time.Sleep(3 * time.Second)
    fmt.Println("stopping ticker")
    ticker.Stop()
    time.Sleep(3 * time.Second)
}

Ausgabe:

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

Wie Sie sehen können, iteriert die Goroutine trotz Anhalten des Tickers unbegrenzt weiter, da der Kanal nicht geschlossen ist.

Lösung:

Eine Möglichkeit, sicherzustellen, dass die Goroutine beendet wird, besteht darin, einen zweiten Kanal wie folgt zu verwenden:

package main

import (
    "fmt"
    "log"
    "time"
)

// Run the function every tick
// Return false from the func to stop the ticker
func Every(duration time.Duration, work func(time.Time) bool) chan bool {
    ticker := time.NewTicker(duration)
    stop := make(chan bool, 1)

    go func() {
        defer log.Println("ticker stopped")
        for {
            select {
            case time := <-ticker.C:
                if !work(time) {
                    stop <- true
                }
            case <-stop:
                return
            }
        }
    }()

    return stop
}

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

    time.Sleep(3 * time.Second)
    fmt.Println("stopping ticker")
    stop <- true
    time.Sleep(3 * time.Second)
}

In diesem Code:

  • Die Every-Funktion erstellt zwei Kanäle: ein Tickerkanal und ein Stoppkanal.
  • Die Goroutine iteriert über beide Kanäle.
  • Wenn die Arbeitsfunktion „false“ zurückgibt, wird der Stoppkanal benachrichtigt, was dazu führt, dass die Goroutine beendet wird.
  • Wenn Stop() aufgerufen wird, sendet es eine Nachricht an den Stop-Kanal, der die Goroutine beendet.

Das obige ist der detaillierte Inhalt vonWie beendet man eine Goroutine ordnungsgemäß, wenn man einen Ticker-Kanal in Golang verwendet?. 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