如何在没有默认值的情况下使 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。
您有三个选择:
使用非阻塞代码,并接受 100% CPU 使用率。
重新设计 checkSomthingIsTrue()
所以它使用一个通道,并且可以放在 select
块中。
for {
select {
case <-ctx.Done():
return true
case <-whenSomethingIsTrue():
if err := doSomthing(); err != nil {
continue
}
}
}
使用超时来限制循环,例如:
// 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
没有任何意义,但这是一个不同的问题。
我有这段代码。
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。
您有三个选择:
使用非阻塞代码,并接受 100% CPU 使用率。
重新设计
checkSomthingIsTrue()
所以它使用一个通道,并且可以放在select
块中。for { select { case <-ctx.Done(): return true case <-whenSomethingIsTrue(): if err := doSomthing(); err != nil { continue } } }
使用超时来限制循环,例如:
// 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
没有任何意义,但这是一个不同的问题。