O servidor http Golang bloqueia quando inicia uma goroutine de loop infinito
Como aprendi com os documentos da golang, se eu definir o tempo de execução.GOMAXPROCS (8) com uma CPU de 8 núcleos (intel i7), inicie uma goroutine de loop infinito, outras gorutines não devem ser bloqueadas porque existem threads e goprocs em uso. Mas isso não é verdade ao usar o pacote net / http, uma goroutine de loop infinito bloqueará o servidor http após algumas invocações. Alguém pode ajudar a explicar o porquê?
Se eu comentar a linha "ir loop infinito", inicie cliente após servidor, o cliente exibirá 1000 asteriscos; mas se eu habilitar a goroutine, o cliente bloqueará após imprimir alguns asteriscosEu tentei adicionar runtime.LockOSThread () na goroutine, parece que não funcionaMeu ambiente: osx 10.10, go version go1.3.1 darwin / amd64Código do servidor:
package main
import (
"fmt"
"log"
"net/http"
"runtime"
)
func myHandler(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("hello"))
}
func infiniteloop() {
for {
}
}
func main() {
// set max procs for multi-thread executing
runtime.GOMAXPROCS(runtime.NumCPU())
// print GOMAXPROCS=8 on my computer
fmt.Println("GOMAXPROCS=", runtime.GOMAXPROCS(-1))
http.Handle("/", http.HandlerFunc(myHandler))
// uncomment below line cause server block after some requests
// go infiniteloop()
if err := http.ListenAndServe(":8280", nil); err != nil {
log.Fatal(err)
}
}
Código do cliente:
package main
import (
"fmt"
"net/http"
)
func getOnce() {
if resp, err := http.Get("http://localhost:8280"); err != nil {
fmt.Println(err)
return
} else {
defer func() {
if err := resp.Body.Close(); err != nil {
fmt.Println(err)
}
}()
if resp.StatusCode != 200 {
fmt.Println("error codde:", resp.StatusCode)
return
} else {
fmt.Print("*")
}
}
}
func main() {
for i := 1; i < 1000; i++ {
getOnce()
if i%50 == 0 {
fmt.Println()
}
}
}
Agora eu sei por que esse loop vazio bloqueia outras goroutines, mas por queruntime.LockOSThread()
também não ajuda?
func infiniteloop() {
// add LockOSThread will not help
runtime.LockOSThread()
for {
}
}
Comohttp://golang.org/pkg/runtime/#LockOSThread mencionado, o loop vazio deve ser executado em um thread independente, e outras goroutines não devem ser impactadas pelo loop ocupado. O que há de errado no meu entendimento?