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

带有 Ticker 的 Goroutine 选择循环导致 CPU 达到 100%

带有 Ticker 的 Goroutine 选择循环导致 CPU 达到 100%

Go
开满天机 2022-06-27 17:10:10
我有这个循环,它的作用是尝试反复轮询另一台服务器。我使用ticker来实现这一点,但是程序反复显示100%的CPU使用率。这个代码在一个 goroutine 中运行。HTTP 服务器在另一个 goroutine 中运行。func() Monitor() {  abort := make(chan bool)  log.Info("Monitor started.")  // start the monitor goroutine  go func() {      defer log.Info("Stopped monitor")              ticker := time.NewTicker(time.Duration(35.0) * time.Second)      defer ticker.Stop()              log.Info("Monitor started! \n")      for {        select {        case t := <-ticker.C:            log.Infof("Subscribe to service at time %v\n", t)            if err := selfConn.SubscribeToService(); err != nil {                log.Errorf("Failed to subscribe to primary connector: %v", err)            }         case <-abort:            log.Info("Finished routine!")            return        default:            continue        }        }    }()       go func() {        time.Sleep(10 * time.Minute)        abort <- true    }()}但是,当监视器循环开始时,每次发送到股票通道的信号时,CPU 都会持续显示 100%。在 goroutine 中使用 ticker 以使其不会消耗 100% CPU,我错过了什么?
查看完整描述

1 回答

?
子衿沉夜

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

你的循环中select有一个default分支。如果其他cases 都没有准备好继续,default则立即执行分支,因此您的下一次迭代立即开始而无需等待。这是一个繁忙的循环。


此外,不需要另一个 goroutine 终止,您可以在同一个 goroutine 中使用计时器。


例如:


func monitor() {

    log.Info("Monitor started.")


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

    defer ticker.Stop()


    timeoutCh := time.After(10 * time.Minute)

    for {

        select {

        case t := <-ticker.C:

            log.Infof("Subscribe to service at time %v\n", t)

            if err := selfConn.SubscribeToService(); err != nil {

                log.Errorf("Failed to subscribe to primary connector: %v", err)

            }

        case <-timeoutCh:

            log.Info("Finished routine!")

            return

        }

    }

}


查看完整回答
反对 回复 2022-06-27
  • 1 回答
  • 0 关注
  • 132 浏览
慕课专栏
更多

添加回答

举报

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