【发布时间】:2013-09-06 15:44:39
【问题描述】:
我在net/http/httptest 中找到了以下代码,想知道空的select 语句在Go 中的作用。
go s.Config.Serve(s.Listener)
if *serve != "" {
fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
select {}
}
【问题讨论】:
标签: go
我在net/http/httptest 中找到了以下代码,想知道空的select 语句在Go 中的作用。
go s.Config.Serve(s.Listener)
if *serve != "" {
fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
select {}
}
【问题讨论】:
标签: go
一个空的select{} 语句永远阻塞。它类似于一个空的for{} 语句。
在大多数(全部?)支持的 Go 架构上,空选择将产生 CPU。一个空的 for 循环不会,即它会在 100% 的 CPU 上“旋转”。
【讨论】:
select 建议的是条件而不是循环。
STOP,一个永远不会继续的过程。这类似于自死锁,我想它不会经常被使用。但是,该问题为这种模式提出了一个有趣且真实的用例。空的for{} 循环是自活锁,不同的是它消耗cpu 资源。
select{} 来阻塞产生CPU 的主goroutine 似乎是惯用的Go。由于主 goroutine 还没有返回,这就离开了进程,可以分析其他 goroutine 的行为。
在 Mac OS X 上,在 Go 中,for { } 将导致 CPU% 达到最大值,并且进程的状态将为 running
另一方面,select { } 不会导致 CPU% 达到最大值,进程的状态将为sleeping
【讨论】:
空的select 语句只是阻塞了当前的goroutine。
至于您为什么要这样做,这是一个原因。这个sn-p是等价的
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 检测起来很简单,并且可能比复制版本的成本为零。
【讨论】: