dongwen3410 2017-09-08 16:15
浏览 27

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

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
", 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
", 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
", i, runtime.NumGoroutine())
            }
        }
        <-t.C
        fmt.Printf("over time:%s
", 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
", 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
", runtime.NumGoroutine())
    }
}

no-block

  • 写回答

1条回答 默认 最新

  • duanfenhui5511 2017-09-13 08:57
    关注

    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

    评论

报告相同问题?

悬赏问题

  • ¥15 shape_predictor_68_face_landmarks.dat
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制