如何在没有默认值的情况下使select case在for循环中不阻塞



我有这段代码。

func Start() bool {
for {
if checkSomthingIsTrue() {
if err := doSomthing(); err != nil {
continue
}
}
select {
case <-ctx.Done():
return true
}
}
}

如何在不使用default:的情况下使上述函数不阻塞。不使用默认情况的原因是它总是消耗100%的CPU。

答案:我已经利用了时间。Ticker to throttle感谢

这里有一个根本的误解。线程只能做两件事:

  • 线程可以阻塞,等待一些东西。

  • 线程可以运行,使用CPU。

如果线程从不阻塞,那么它将使用100%的可用CPU您不能使非阻塞代码使用少于100%的可用CPU

你有三个选择:

  1. 使用非阻塞代码,并接受100%的CPU使用率。

  2. 重新设计checkSomthingIsTrue(),使其使用通道,并且可以放在select块中。

    for {
    select {
    case <-ctx.Done():
    return true
    case <-whenSomethingIsTrue():
    if err := doSomthing(); err != nil {
    continue
    }
    }
    }
    
  3. 使用超时来限制循环,例如:

    // Poll every 100ms.
    const pollInterval = 100 * time.Millisecond
    for {
    select {
    case <-ctx.Done():
    return true
    case <-time.After(pollInterval):
    if checkSomthingIsTrue() {
    if err := doSomthing(); err != nil {
    continue
    }
    }
    }
    }
    

还要注意,continue没有任何意义,但这是一个不同的问题。

最新更新