goroutine很快在被请求时阻止了http服务器 [英] goroutine soon blocked the http server when it was requested

查看:198
本文介绍了goroutine很快在被请求时阻止了http服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

goroutine在请求http服务器时阻塞了它

以下代码将很快被阻止

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

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 {

    }
}

阻止

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

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())
    }
}

无障碍

推荐答案

我认为没有切换点.
Go调度程序是非抢占式的. (合作)
所有goroutine必须配合调度

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
    }
}



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



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

这篇关于goroutine很快在被请求时阻止了http服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆