goroutine很快在请求时阻止了http服务器

时间:2017-09-08 16:15:35

标签: http go block goroutine

goroutine在需要使用http服务器时sooblocked

以下代码很快就会被阻止

在设备管理功能中,通过访问http REST ful接口来判断设备是否在线,30s访问1000个设备,当前程序大致如下,看看goroutine的数量不是很高,但很快程序不会移动,cpu,内存不会占用太高

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

以下代码不会阻止,这就是为什么,希望能给我一些建议,谢谢

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 个答案:

答案 0 :(得分:0)

我认为没有切换点 Go调度程序不是先发制人的。 (合作)
所有goroutine必须合作安排

func main() {
    go c()
    for {
        // it is not cooperative
    }
}



Go调度程序只能在特定点切换。
具体点是I / O,chan,Sleep,Gosched

在块示例

上尝试下面的代码
func main() {
    go c()
    for {
        runtime.Gosched() // or time.Sleep(any)
    }
}


我希望这会对你有所帮助