繁体   English   中英

Golang for select 循环消耗 100% 的 cpu

[英]Golang for select loop consumes 100% of cpu

我有一个需要加载的资源,然后才允许对其进行任何访问。 它还需要每分钟更新一次。

通道的长度为 1 struct{},因此如果资源尚未加载,则循环将被阻塞。

下面的这段代码开始使用我 100% 的 cpu,我尝试添加

time.Sleep(10 * time.Millisecond)

这使得应用程序cpu消耗下降到1%

我认为自动收报机将是定时收藏的更好选择。

任何想法为什么它会消耗 100% cpu 或任何更好的实现想法?

func (al *AsyncLoop) Run() {
    go func() {
        for {
            select {
            case <-al.chanFetchRequest:
                if al.fetched == false {
                    al.fetchData()
                } else if al.lastUpdated.Add(1*time.Minute).Unix() < time.Now().Unix() && al.fetching == false {
                    go al.fetchData()
                }
                al.chanFetchResponse <- struct{}{}
                continue
            default:
                continue
            }
        }
    }()
}

我认为你只是在有新数据时发布到 al.chanFetchRequest 所以我认为你必须一直从这个频道阅读。 向选择中添加代码可能会导致您获取数据,即使它没有更改或(更糟)在它加载之前。 为什么不,在正常情况下,每次获取数据时都花点时间,然后确保在再次获取数据之前等待了足够的时间。 像这样的东西:

        var nextFetch time.Time
        for {
            select {
            case <-al.chanFetchRequest:
                if al.fetched == false {
                    al.fetchData()
                    nextFetch = time.Now().Add(1 * time.Minute)
                } else if time.Now().After(nextFetch) {
                    al.fetchData()
                    nextFetch = time.Now().Add(1 * time.Minute)
                }
                al.chanFetchResponse <- struct{}{}
            }
        }

default语句创建一个非阻塞无限循环,导致 100% 的 cpu 使用率。 当 case 的条件不满足时,循环进入默认的非阻塞无限循环。

删除default将解决问题。 但是会有一个 linter 警告S1000: should use for range instead of for { select {} }通知select对单通道没有意义。

最终代码将是

for {
    _ := <-al.chanFetchRequest
    if al.fetched == false {
        al.fetchData()
        nextFetch = time.Now().Add(1 * time.Minute)
    } else if time.Now().After(nextFetch) {
        al.fetchData()
        nextFetch = time.Now().Add(1 * time.Minute)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM