Home > Backend Development > Golang > How to Properly Terminate a Goroutine When Using a Ticker Channel in Golang?

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

Patricia Arquette
Release: 2024-11-07 19:16:02
Original
507 people have browsed it

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

Ticker Channel Behavior in Golang

If you iterate over a ticker channel and call Stop(), the channel will pause but not close. This can lead to goroutines remaining active indefinitely.

Case Example:

Consider the following code snippet:

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)
}
Copy after login

Output:

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
Copy after login

As you can see, despite stopping the ticker, the goroutine continues to iterate indefinitely because the channel is not closed.

Solution:

One way to ensure the goroutine terminates is to use a second channel as follows:

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)
}
Copy after login

In this code:

  • The Every function creates two channels: a ticker channel and a stop channel.
  • The goroutine iterates over both channels.
  • If the work function returns false, the stop channel is notified, causing the goroutine to exit.
  • When Stop() is called, it sends a message to the stop channel, which terminates the goroutine.

The above is the detailed content of How to Properly Terminate a Goroutine When Using a Ticker Channel in Golang?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template