我对Go的例程并不是很熟悉,但是因为我正在使用路由器,net/http所以我看到了几次ListenAndServe()被go例程包裹起来.
服务器需要能够同时处理多个请求以提高效率.那么为什么要使用例程作为"轻量级线程"呢?并发性是否具有任何优势?
这是OpenShift的一个例子
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello OpenShift!")
}
func main() {
http.HandleFunc("/", helloHandler)
go func() {
fmt.Println("serving on 8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic("ListenAndServe: " + err.Error())
}
}()
go func() {
fmt.Println("serving on 8888")
err := http.ListenAndServe(":8888", nil)
if err != nil {
panic("ListenAndServe: " + err.Error())
}
}()
select {}
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*ier 15
http.ListenAndServe是一个阻止电话.如果你想做一个更多的工作(比如http.ListenAndServe再打一次),你需要把它移到一个单独的goroutine上.这就是他们在这里所做的一切.
他们select{}最后用来阻挡主要的goroutine,因为他们所有的呼叫http.ListenAndServe都在其他goroutine上.如果他们没有打电话select{},该程序将终止,因为main()将返回.
他们可以通过删除select{}和删除go func()最后一个代码块周围的包装器来实现相同的功能.但我怀疑他们是这样做的,所以所有代码都是一致的.
但这与性能无关.
在评论中,您提供了一些类似的其他示例.在第一个例子中:
func main() {
http.HandleFunc("/", responsehandler.Handler)
go func() {
http.ListenAndServe(":8888", nil)
}()
fileservice.NewWatcher()
}
Run Code Online (Sandbox Code Playgroud)
这会调用http.ListenAndServe然后调用fileservice.NewWatcher()(阻塞).如果他们没有把话题包裹在goroutine中,fileservice.NewWatcher()就永远不会被召唤.
func init() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
}
Run Code Online (Sandbox Code Playgroud)
这将打开调试分析器Web服务器.同样,它是一个goroutine,因此调用init立即返回而不是阻塞.这种特殊情况允许调用者只是import _ "profiling""神奇地"获得调试分析器Web服务器.
| 归档时间: |
|
| 查看次数: |
5720 次 |
| 最近记录: |