gpt4 book ai didi

multithreading - 重置股票行情

转载 作者:行者123 更新时间:2023-12-01 21:23:59 26 4
gpt4 key购买 nike

考虑一个使用计时器/股票代码资源初始化的服务器,该服务器将触发每个t(在我的示例中t为20ms)的滴答声。每次服务器监听网络上的某些内容(例如来自对等方的定期信号)时,都必须重置计时器。另一方面,如果计时器在没有重置的情况下到期(例如,其所有对等节点都已死),则它将触发某些事件(在我的示例中,我只是打印从程序开始的时间)。

我在使用time.Ticker实现此行为时遇到了麻烦。重置计时器似乎可以正常工作(在最初的50毫秒内不会触发),但是此后计时器没有激活(不会每20毫秒计时一次)。

package main

import (
"fmt"
"time"
)

var wallclock time.Time

type server struct {
timeout *time.Ticker
stop chan bool
}

func (srv *server) start() {
for {
select {
case <-srv.timeout.C:
{
elapsed := time.Since(wallclock)
fmt.Println("timed out after ", elapsed, " elapsed from start ")
}
case <-srv.stop:
{
return
}
}
}
}

func main() {
wallclock = time.Now()
//make the server with a timer that will fire every 20ms
srv := server{
timeout: time.NewTicker(20 * time.Millisecond),
//channel to indicate the server to stop listening
stop: make(chan bool),
}
//start listening on a different thread
go srv.start()
for i := 0; i < 5; i++ {
//reset it every 10ms
time.Sleep(10 * time.Millisecond)
srv.timeout.Stop()
//as the reset frequency is higher,
//I'm not expecting this to fire within
//the first 50ms (5*10ms)
srv.timeout = time.NewTicker(20 * time.Millisecond)
}
//sleep for 110ms
//I'm expecting the timer to fire at least 5 times here
time.Sleep(110 * time.Millisecond)
//stop listening
srv.stop <- true
fmt.Println("Hi from tckr!")
}

我希望看到类似的东西
timed out after ~70ms elapsed from start
timed out after ~90ms elapsed from start
timed out after ~110ms elapsed from start
timed out after ~130ms elapsed from start
timed out after ~150ms elapsed from start
Hi from tckr!

五次,因为我让主线程 sleep 了110毫秒,而20毫秒的计时器可能会在此间隔内触发五次。

但是我只看到 Hi from tckr!srv.timeout = time.NewTicker(20 * time.Millisecond)是重置 Ticker的正确方法吗?

如果我不停止 for循环( srv.timeout.Stop())内的股票行情,股票行情似乎一直在行情。这是注释 srv.timeout.Stop()后的示例输出。
timed out after  20.6872ms  elapsed from start
timed out after 41.4278ms elapsed from start
timed out after 61.8747ms elapsed from start
timed out after 72.7793ms elapsed from start
timed out after 94.1448ms elapsed from start
timed out after 112.5283ms elapsed from start
timed out after 134.0131ms elapsed from start
timed out after 152.5846ms elapsed from start
Hi from tckr!

我不希望代码在前50毫秒内触发(即,我不想看到前两行分别为20.6872毫秒和41.4278毫秒)。

最佳答案

记住,for select statements:

For all the cases in the statement, the channel operands of receive operations and the channel and right-hand-side expressions of send statements are evaluated exactly once, in source order, upon entering the "select" statement. The result is a set of channels to receive from or send to, and the corresponding values to send.



这意味着,一旦 start输入其 select语句,它就会评估 srv.timeout.C并保留在 channel 上;输入 srv.timeout后对 select进行的任何更改都不会影响 select,它将仍在等待从以前的 channel 接收。

您可以通过添加另一个 channel (在此处的示例中称为 ping)来解决此问题,以便您可以向 start发出该 channel 正在更改的信号(或将整个重置逻辑移至 start):
type server struct {
timeout *time.Ticker
stop chan bool
ping chan struct{}
}

func (srv *server) start() {
for {
select {
case <-srv.timeout.C:
elapsed := time.Since(wallclock)
fmt.Println("timed out after ", elapsed, " elapsed from start ")
case <-srv.ping:
// do nothing & let the loop iterate
// OR
srv.timeout.Stop()
srv.timeout = time.NewTicker(20 * time.Millisecond)
case <-srv.stop:
return
}
}
}

// in main()
go srv.start()
for i := 0; i < 5; i++ {
//reset it every 10ms
time.Sleep(10 * time.Millisecond)
srv.ping <- struct{}{}

// possibly shift the below logic to start()'s ping handler case
srv.timeout.Stop()
srv.timeout = time.NewTicker(20 * time.Millisecond)
}

关于multithreading - 重置股票行情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58328602/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com