当前位置: 首页 > 知识库问答 >
问题:

go select case 问题?

方野
2023-11-15
    ticker1 := time.NewTicker(3 * time.Second)    ticker2 := time.NewTicker(3 * time.Second)    fmt.Println("当前时间为:", time.Now())    go func() {        for {            select {            case <-ticker1.C:                t := <-ticker1.C                fmt.Println("当前时间为=1=:", t)            }        }    }()    go func() {        for {            //从定时器中获取数据            t := <-ticker2.C            fmt.Println("当前时间为=2=:", t)        }    }()

如代码所示
目的都是像间隔3s执行一次
但是实际执行的时候 1 执行一次要比 2 间隔更久
image.png
因为最近在弄一个线上项目 这个周期本来是设定10s的最后变成了 一分多钟才执行一次
好奇是什么问题导致的?

共有3个答案

孟俊晖
2023-11-15

ticker1.C是一个管道,select case <- ticker1.C 实际上就已经读取了一次管道了。下面的t := <- ticker1.C 是读取第二次。定时器每隔3s向ticker1.C写入一次时间。你等待第二次读,不就是6s才会输出ticker1的时间吗。

秦博达
2023-11-15

1 读了两次,是两个周期。

可以直接写 case t := <-ticker1.C

弘和同
2023-11-15

这个问题可能是由于 Go 语言的 select 语句的工作方式导致的。在 select 语句中,Go 语言会随机选择一个可用的 case 来执行。这意味着,如果多个 case 都准备好了,Go 语言会随机选择一个执行,而不是按照顺序或者其他方式选择。

在你的代码中,ticker1ticker2 都是每3秒发送一次时间。但是,由于 select 语句的随机选择行为,ticker1 可能在 ticker2 之前或者之后被执行。如果 ticker1 先被执行,那么它将会阻塞 select 语句,直到3秒后再次执行。而在这3秒内,ticker2 可能已经执行了多次。

解决这个问题的一个方式是使用 time.Tick 方法代替 select 语句。time.Tick 方法会定期返回一个通道,这个通道会在每次调用 time.Tick 时被填充一个新的时间。这样,你可以在两个定时器之间同步时间,而不是依赖 select 语句的随机选择行为。

下面是一个使用 time.Tick 的例子:

ticker1 := time.NewTicker(3 * time.Second)ticker2 := time.NewTicker(3 * time.Second)fmt.Println("当前时间为:", time.Now())go func() {    for t := range ticker1.C {        fmt.Println("当前时间为=1=:", t)    }}()go func() {    for t := range ticker2.C {        fmt.Println("当前时间为=2=:", t)    }}()

在这个例子中,我们使用 range 代替了 select 语句。这样,每个定时器都会在自己的循环中等待自己的通道被填充,从而实现了同步。

 类似资料:
  • 问题内容: 包括: all Spring libs, Apache Tomcat 7.0 library 在构建路径中 但它仍然给出错误: 在“ org.sprintframework.web-3.1.0.M1.jar”中,我可以看到“ org.springframework.web.context.ContextLoaderListener”。 Google上的某个人说应该包含spring.ja

  • 问题内容: 我使用非常简单的代码返回XML 但是,出现以下错误 请帮忙。谢谢 问题答案: 运行时出现NoSuchMethodError表示你使用的库版本与生成代码所针对的版本不同。 在你的情况下,Spring是元凶。在运行时检查类路径上的内容,并确保以下各项: 版本与编译时间罐相同 如果存在多个版本,请删除不需要的版本

  • 问题内容: 我不明白注释和之间的实际区别是什么? 扩展名还是它们具有完全不同的含义?什么时候应该使用它们?在服务层中使用Spring ,在DAO 中使用javax? 谢谢回答。 问题答案: 几年前,Spring定义了自己的Transactional注释以使Spring bean方法具有事务性。 Java EE 7终于做了同样的事情,现在除了EJB方法外,还允许CDI bean方法是事务性的。因此,

  • 我在CentOS虚拟机中安装了RabbitMQ,该虚拟机的网络适配器被定义为Bridge。我正在尝试配置RabbitMQ管理,以便通过机器的IP地址访问WebApp。配置如下:

  • 这个FAQ的最新版本总是可以从Apache主站点得到,位于<http://httpd.apache.org/docs/2.2/faq/> 如果你的问题在这里没有找到答案,你也可以看看Apache 1.3 FAQ ,看你的问题是否在那里有了答案。 主题 背景 关于 Apache HTTP Server 的背景知识。 支持 我遇到问题该怎么办? 错误信息 这些错误信息是什么意思? 背景 什么是Apac

  • 发布问题 更新问题 设置问题悬赏 获取问题列表 获取一个问题详情 删除一个问题 获取用户发布的问题列表 发布问题 POST /questions 输入 字段 类型 描述 subject 字符串 必须,问题主题或者说标题,不能超过 255 字节 ,必须以 ? 结尾。(不区分全角或者半角) topics 数组 必须,绑定的话题,数组子节点必须符合 { "id": 1 } 的格式。 body 字符串

  • 问题内容: 我简直不敢相信我网站上正在发生的事情。当我添加此行时: 一切正常。如果我不这样做,CSS就会“混乱”,一切都会变得不同,布局也会变得“丑陋”。 这条线如何解决所有问题? 问题答案: 您正在将HTML与XHTML混合使用。 通常,声明用于区分HTMLish语言的版本(在这种情况下为HTML或XHTML)。 不同的标记语言将表现不同。我最喜欢的例子是。在浏览器中查看以下内容: XHTML

  • 我试图在fabric rocket chat上联系,但没有得到太多帮助,因此在SO上发布了它。我有以下疑问: 我们是否可以在链码内访问块高度(我知道这在客户端是可行的,但在链码内是否可能) 可以从链码中的正在进行的事务调用新事务吗? 想知道hyperledger Fabric中存储的数据的历史记录在哪里 我们可以根据链码中的transactionid进行查询吗? 在fabric链码中编写调度程序是