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

我有这段代码。

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

如何在不使用default:case 的情况下使上述函数非阻塞。不使用默认情况的原因是因为它总是占用 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这没有任何意义,但这是一个不同的问题。

  • @nipuna: Sure, if you prefer, you can use `Ticker`. The timing will be different.

以上是如何在没有默认值的情况下在for循环中使selectcase非阻塞的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>