猿问

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)

}

运行产生:


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

所以那个 goroutine 永远不会退出。有没有更好的方法来处理这种情况?我应该关心 goroutine 永远不会退出吗?


浮云间
浏览 270回答 3
3回答

烙印99

在第二个通道上发出“完成”信号,并在你的 goroutine 中选择股票代码和完成通道。根据您真正想做的事情,可能存在更好的解决方案,但这很难从简化的演示代码中看出。

汪汪一只猫

按照沃尔克的建议使用第二个频道。这就是我最终运行的内容:package mainimport (&nbsp; &nbsp; "log"&nbsp; &nbsp; "time")// Run the function every tick// Return false from the func to stop the tickerfunc Every(duration time.Duration, work func(time.Time) bool) chan bool {&nbsp; &nbsp; ticker := time.NewTicker(duration)&nbsp; &nbsp; stop := make(chan bool, 1)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; defer log.Println("ticker stopped")&nbsp; &nbsp; &nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case time := <-ticker.C:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if !work(time) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stop <- true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case <-stop:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()&nbsp; &nbsp; return stop}func main() {&nbsp; &nbsp; stop := Every(1*time.Second, func(time.Time) bool {&nbsp; &nbsp; &nbsp; &nbsp; log.Println("tick")&nbsp; &nbsp; &nbsp; &nbsp; return true&nbsp; &nbsp; })&nbsp; &nbsp; time.Sleep(3 * time.Second)&nbsp; &nbsp; log.Println("stopping ticker")&nbsp; &nbsp; stop <- true&nbsp; &nbsp; time.Sleep(3 * time.Second)}

牛魔王的故事

你可以这样做。package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "time")func startTicker(f func()) chan bool {&nbsp; &nbsp; done := make(chan bool, 1)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; ticker := time.NewTicker(time.Second * 1)&nbsp; &nbsp; &nbsp; &nbsp; defer ticker.Stop()&nbsp; &nbsp; &nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case <-ticker.C:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case <-done:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("done")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()&nbsp; &nbsp; return done}func main() {&nbsp; &nbsp; done := startTicker(func() {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("tick...")&nbsp; &nbsp; })&nbsp; &nbsp; time.Sleep(5 * time.Second)&nbsp; &nbsp; close(done)&nbsp; &nbsp; time.Sleep(5 * time.Second)}
随时随地看视频慕课网APP

相关分类

Go
我要回答