空select{}的可能用法是什么?



我理解空select{}永远阻塞go-Routine,但无法理解这迎合了哪些不同的用例?

我也检查去repo找到更多的使用,我只能找到两个实现,一个在sycall/js和另一个在httptest.

func handleEvent() {
cb := jsGo.Get("_pendingEvent")
if cb.IsNull() {
return
}
jsGo.Set("_pendingEvent", Null())
id := uint32(cb.Get("id").Int())
if id == 0 { // zero indicates deadlock
select {}
}
funcsMu.Lock()
f, ok := funcs[id]
funcsMu.Unlock()
if !ok {
Global().Get("console").Call("error", "call to released function")
return
}
this := cb.Get("this")
argsObj := cb.Get("args")
args := make([]Value, argsObj.Length())
for i := range args {
args[i] = argsObj.Index(i)
}
result := f(this, args)
cb.Set("result", result)
}

在httptest中的用法

// Start starts a server from NewUnstartedServer.
func (s *Server) Start() {
if s.URL != "" {
panic("Server already started")
}
if s.client == nil {
s.client = &http.Client{Transport: &http.Transport{}}
}
s.URL = "http://" + s.Listener.Addr().String()
s.wrap()
s.goServe()
if serveFlag != "" {
fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
select {}
}
}

这里的问题是select {}在这里是如何使用的,如果有任何其他用途,我们可以利用select {}?

select {}永远阻塞当前的程序。

显然,用例就是当你需要这样做的时候。这应该是非常罕见的情况。

第一个例子使用它在主例程中强制死锁,因为eventID0是不可能的。

第二个例子是代码气味。您几乎总是可以用一种不需要阻塞程序的方式来构建代码。例如,s.goServe()可以重构为s.serve(),然后可以阻塞或非阻塞方式调用,分别使用s.serve()go s.serve()

最新更新