英文:
What does an empty select do?
问题
在Go语言中,select {}
语句是一个空的select
语句。select
语句用于在多个通信操作中选择一个可执行的操作。在这种情况下,空的select
语句被用作无限循环,它会一直阻塞程序的执行,直到收到一个可执行的通信操作。这样做的目的可能是为了保持程序的运行,以便能够处理其他的并发操作或等待其他事件的发生。
英文:
I found the following code in net/http/httptest
and wonder what the empty select
statement does in Go.
go s.Config.Serve(s.Listener)
if *serve != "" {
fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
select {}
}
答案1
得分: 51
一个空的select{}
语句会永远阻塞。它类似于一个空的for{}
语句。
在大多数(所有?)支持的Go架构上,空的select语句会让出CPU。而空的for循环不会,也就是说它会在100%的CPU上“自旋”。
英文:
An empty select{}
statement blocks forever. It is similar to an empty for{}
statement.
On most (all?) supported Go architectures, the empty select will yield CPU. An empty for-loop won't, i.e. it will "spin" on 100% CPU.
答案2
得分: 23
在Mac OS X上,使用Go语言的for { }
会导致CPU使用率达到最大值,并且进程的状态为running
。
另一方面,使用select { }
不会导致CPU使用率达到最大值,进程的状态为sleeping
。
英文:
On Mac OS X, in Go, for { }
will cause the CPU% to max, and the process's STATE will be running
select { }
, on the other hand, will not cause the CPU% to max, and the process's STATE will be sleeping
答案3
得分: 10
空的select
语句只是阻塞当前的goroutine。
至于为什么要这样做,这里有一个原因。这段代码等同于:
if *serve != "" {
fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
s.Config.Serve(s.Listener)
} else {
go s.Config.Serve(s.Listener)
}
这种写法更好,因为没有浪费goroutine。但它的缺点是代码重复。作者优化的目标是减少代码重复而不是浪费资源。不过需要注意的是,永久阻塞的goroutine很容易检测,并且可能在重复版本上没有额外的开销。
英文:
The empty select
statement just blocks the current goroutine.
As for why you'd do this, here is one reason. This snippet is equivalent
if *serve != "" {
fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
s.Config.Serve(s.Listener)
} else {
go s.Config.Serve(s.Listener)
}
It's better in that there isn't a wasted goroutine. It's worse in that now there is code repetition. The author optimized for less code repetition over a wasted resource. Note however the permanently block goroutine is trivial to detect and may have zero cost over the duplicating version.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论