如何解决空 select{} 的可能用例是什么
我知道空的 select{}
会永远阻塞 go-Routine,但无法理解这适合所有不同的用例吗?
我还检查了 go repo 以找到更多用法,我只能找到两个实现,一个在 syscall/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 {}
永远阻塞当前的 goroutine。
很明显,一个用例是您需要这样做。这种情况应该是非常罕见的。
第一个示例使用它在主协程中强制死锁,因为 eventID 0
是不可能的。
但第二个例子是代码异味。
您几乎总是可以以不需要阻塞这样的 goroutine 的方式来构建代码。例如,可以将 s.goServe()
重构为 s.serve()
,然后可以分别使用 s.serve()
或 go s.serve()
以阻塞或非阻塞方式调用它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。