douceng7070 2018-01-17 22:38
浏览 40
已采纳

触发和停止时间手动在Golang中的股票行情通道

So I have this code, it accepts user entry of one, two, or three. It prints Ticker ticked depending on the duration selected. I need help on how to stop the ticker first before activating the ticker again with a different duration.

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
    "time"
)

func main() {
    reader := bufio.NewReader(os.Stdin)

    for {
        fmt.Print("> ")

        text, _ := reader.ReadString('
')
        text = strings.Replace(text, "
", "", -1)

        switch text {
        case "one":
            go timeTick(true, 1)
        case "two":
            go timeTick(true, 2)
        case "three":
            go timeTick(true, 3)
        default:
            go timeTick(false, 0)
        }
    }
}

func timeTick(flag bool, tick int) {
    var tickChan *time.Ticker

    if flag {
        tickChan = time.NewTicker(time.Second * time.Duration(tick))
    }

    doneChan := make(chan bool)

    if !flag {
        doneChan <- true
    }

    for {
        select {
        case <-tickChan.C:
            fmt.Println("Ticker ticked")
        case <-doneChan:
            fmt.Println("Done")
            return
        }
    }
}

So user inputs either, one, two, or three to activate the ticker else it will send true to doneChan channel.

When I activated the ticker with one. It prints Ticker ticked every second but how do I stop the ticker when I input two or three while the ticker is running? It then brings me to my main question, why is doneChan not triggered at all even inputting a random string?

  • 写回答

2条回答 默认 最新

  • dqyq88053 2018-01-18 00:56
    关注

    You need to pass in the channel used to signal completion. You always want to cancel the current ticker if there is one, so you can attempt a send in each iteration of the main for loop. Since the channel isn't buffered, a send operation is blocking, so you need to attempt the send in a select statement with a default case to prevent a deadlock in the case you don't have a current ticker attempting to read from the channel.

    package main
    
    import (
        "bufio"
        "fmt"
        "os"
        "strings"
        "time"
    )
    
    func main() {
        reader := bufio.NewReader(os.Stdin)
        tickerDone := make(chan struct{})
    
        for {
            fmt.Print("> ")
    
            text, _ := reader.ReadString('
    ')
            text = strings.Replace(text, "
    ", "", -1)
    
            select {
            case tickerDone <- struct{}{}:
            default:
            }
    
            switch text {
            case "one":
                go timeTick(1, tickerDone)
            case "two":
                go timeTick(2, tickerDone)
            case "three":
                go timeTick(3, tickerDone)
            }
        }
    }
    
    func timeTick(tick int, done <-chan struct{}) {
        tickChan := time.NewTicker(time.Second * time.Duration(tick))
    
        for {
            select {
            case <-tickChan.C:
                fmt.Println("Ticker ticked")
            case <-done:
                fmt.Println("Done")
                return
            }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站