问题
goroutine sooblocked the http server when it was reqn uested
The following code will soon be blocked
In a device management function, by visiting the http REST ful interface to determine whether the device is online, 30s access to 1000 devices, the current program is roughly as follows to see the number of goroutine is not very high, but soon the program will not Move, cpu, memory is not occupied too high
package main
import (
"fmt"
"net/http"
"runtime"
"time"
)
func a() {
b()
//.....
}
var bb = 0
func b() {
fmt.Printf("b:%d\n", bb)
bb++
resp, err := http.Get("http://www.baidu.com")
if err == nil {
resp.Body.Close()
}
//...
}
func c() {
t := time.NewTicker(time.Second * 30)
for {
fmt.Printf("start time:%s\n", time.Now().Format("15:04:05"))
bb = 0
for i := 0; i < 1000; i++ {
go a()
if i%11 == 0 {
time.Sleep(time.Millisecond * 300)
fmt.Printf("i:%d go:%d\n", i, runtime.NumGoroutine())
}
}
<-t.C
fmt.Printf("over time:%s\n", time.Now().Format("15:04:05"))
}
}
func main() {
go c()
for {
}
}
block
The following code will not block,This is why, hope to give me some advice, thank you
package main
import (
"fmt"
"net/http"
"runtime"
"time"
)
func a() {
b()
}
var bb = 0
func b() {
fmt.Printf("b:%d\n", bb)
bb++
resp, err := http.Get("http://www.baidu.com")
if err == nil {
resp.Body.Close()
}
}
func main() {
for {
for {
go b()
time.Sleep(time.Millisecond * 10)
fmt.Printf("go:%d\n", runtime.NumGoroutine())
}
}
no-block
回答1:
I think there is no switching point.
the Go scheduler is non preemptive. (cooperative)
all goroutines must be cooperative of scheduling
func main() {
go c()
for {
// it is not cooperative
}
}
the Go scheduler can switch only at specific points.
specific points is I/O, chan, Sleep, Gosched
try below code on block example
func main() {
go c()
for {
runtime.Gosched() // or time.Sleep(any)
}
}
I hope this would help you
来源:https://stackoverflow.com/questions/46120712/goroutine-soon-blocked-the-http-server-when-it-was-requested