1 回答

TA贡献1860条经验 获得超8个赞
你的原始例子产生了这个
.
.
tick.
.
.
tick.
.
.
tick.
.
.
tick.
.
.
tick.
BOOM!
Wheraeas您的第二个示例产生了这个
[process took too long]
区别在于您在该default案例中所做的事情。default案例总是可以运行,因此select带有默认语句的案例永远不会阻塞。第二个示例绕循环运行,不断选择准备运行的分支之一(大小写或默认)。您现在想知道为什么计时器永远不会触发。那是因为go例程没有被抢先调度。因此,由于下面的循环永远不会执行任何IO,因此时间间隔永远不会触发。
for {
select {
// whatever
default:
}
}
有许多解决此问题的方法。首先,您可以像在第一个示例中那样放置一些IO。或者你可以放入一个runtime.Gosched()。或者你可以允许 go 运行时使用多个线程与runtime.GOMAXPROCS(2)所有这些都可以工作。
恕我直言,最好的方法是完全不使用默认语句,就像这样。没有默认语句的选择将阻塞,直到其中一个case语句准备就绪。如果要进行一些后台处理(您在默认语句中所做的处理),请启动goroutine-这是可行的方法!
实际上,我在select语句中已经看到很多默认问题,所以我很想说永远不要使用它们。
- 1 回答
- 0 关注
- 153 浏览
添加回答
举报