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

How to make a select case non-blocking in for loop without default

我有这段代码。

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

如何在不使用 default: 的情况下使上述功能非阻塞。 不使用默认大小写的原因是因为它总是吃掉 100% CPU。

回答: 我已经使用 time.Ticker 来节流 谢谢

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

  • 线程可以阻塞,等待某事。

  • 线程可以 运行, 使用 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 没有任何意义,但这是一个不同的问题。