go - 空选择{}的可能用例是什么
问题描述
我知道空select{}
会永远阻塞 go-Routine,但不明白这能满足所有不同的用例吗?
我还检查了去 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。
一个用例是当你需要这样做时,显然。这应该是极其罕见的情况。
第一个示例使用它来强制主 goroutine 中的死锁,因为 eventID0
是不可能的。
但第二个例子是代码异味。你几乎总是可以用一种不需要阻塞这样的 goroutine 的方式来构造代码。例如,s.goServe()
可以重构为,然后可以分别使用或s.serve()
以阻塞或非阻塞方式调用它。s.serve()
go s.serve()
推荐阅读
- python - 在 Python Jupyter Notebook 中创建 BeakerX TableDisplay?
- c# - 离开页面时记住级联下拉值
- amazon-web-services - 当我在 aws api 网关中使用 Http 代理集成时,会引发 500 内部服务器错误且端点地址无效?
- javascript - 如何定位一个
在一个 - python - 在数据框中的一列中搜索特定单词
- delphi - Delphi 如何使用微软语音识别 API
- sql - SQL Server 将 FieldValue 转置为 FieldName
- python - 如何在 matplotlib.pyplot 中绘制递归函数?
- html - 通用标记/ vscode目录不起作用
- python - 如何在具有相似名称和相同类型的多个对象上调用方法?