为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 中的 Ticker Stop 行为

Golang 中的 Ticker Stop 行为

Go
浮云间 2021-05-30 13:16:13
如果我在股票行情频道上测距并调用 stop(),则该频道将停止但未关闭。在这个例子中:package mainimport (    "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)}运行产生:2013/07/22 14:26:53 tick2013/07/22 14:26:54 tick2013/07/22 14:26:55 tick2013/07/22 14:26:55 stopping ticker所以那个 goroutine 永远不会退出。有没有更好的方法来处理这种情况?我应该关心 goroutine 永远不会退出吗?
查看完整描述

3 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

在第二个通道上发出“完成”信号,并在你的 goroutine 中选择股票代码和完成通道。

根据您真正想做的事情,可能存在更好的解决方案,但这很难从简化的演示代码中看出。


查看完整回答
反对 回复 2021-06-21
?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

按照沃尔克的建议使用第二个频道。这就是我最终运行的内容:


package main


import (

    "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 {

        log.Println("tick")

        return true

    })


    time.Sleep(3 * time.Second)

    log.Println("stopping ticker")

    stop <- true

    time.Sleep(3 * time.Second)

}


查看完整回答
反对 回复 2021-06-21
?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

你可以这样做。


package main


import (

    "fmt"

    "time"

)


func startTicker(f func()) chan bool {

    done := make(chan bool, 1)

    go func() {

        ticker := time.NewTicker(time.Second * 1)

        defer ticker.Stop()

        for {

            select {

            case <-ticker.C:

                f()

            case <-done:

                fmt.Println("done")

                return

            }

        }

    }()

    return done

}


func main() {

    done := startTicker(func() {

        fmt.Println("tick...")

    })

    time.Sleep(5 * time.Second)

    close(done)

    time.Sleep(5 * time.Second)

}


查看完整回答
反对 回复 2021-06-21
  • 3 回答
  • 0 关注
  • 269 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信