dqj29136 2018-04-15 20:04
浏览 50

Golang异步和CPU使用率

I am learning Go concurrency, and my expectation is that using goroutines and channels should increase the concurrency. The program takes a few milliseconds to complete. But as the load increases the execution time keeps increasing though there is good amount of CPU idle.

I am sending 1200 QPS/TPS to the program below to analyze the request to response times, and I see that overall execution time of the program increases over time. Also, the CPU usage is around 3-6%.

As I increase the QPS to 100,000, the execution time of the program increases to seconds (from milliseconds initially). But the CPU usage remains at 8-9%.

So why doesn't the program use the other 90-94% of the available CPU and complete execution of the program more quickly?

ulimit -n is 2000000.

package main

import (
    "fmt"
    "github.com/valyala/fasthttp"
    "strings"
    "sync"
)

func total(in chan int, out chan int) {
    res := 0
    for iter := range in {
        res += iter
    }
    out <- res // sends back the result
}

func check() {

    ch := make(chan int)
    rch := make(chan int)
    go total(ch, rch)
    ch <- 1
    ch <- 2
    ch <- 3
    close(ch)       // this will end the loop in the total function
    result := <-rch // waits for total to give the result
    fmt.Println("Total is ", result)
}

func main() {
    var wg sync.WaitGroup
    wg.Add(1)

    go func() {
        m := func(ctx *fasthttp.RequestCtx) {

            maingetpath := ctx.Path()
            urlPart := strings.Split(string(maingetpath), "/")
            func := urlPart[1]
            switch string(func) {
            case "white":
                check()
            default:
                ctx.Error("not found", fasthttp.StatusNotFound)
            }
        }

        fasthttp.ListenAndServe(":8080", m)
        defer wg.Done()
    }()

    wg.Wait()
}
  • 写回答

1条回答 默认 最新

  • dream2891 2018-04-16 00:30
    关注

    I am not sure exactly what you are trying to do in this little server.

    1) You are creating a WaitGroup and adding 1 to it, calling a anonymous go routine, and waiting in main, this does nothing more then move your main to the anonymous function.

    2) Lets look at what your are doing in the check and total functions:

    func total(in chan int, out chan int) {
        res := 0
        // this will just pull the value, and then wait till the next value 
        // is pushed... till you close the "in" channel
        for iter := range in {
            res += iter
        }
        out <- res // sends back the result
    }
    
    func check() {
    
        ch := make(chan int)
        rch := make(chan int)
        go total(ch, rch)
        // we are pushing this value into a unbuffered channel...
        ch <- 1  // this gets pushed and waits until it is pulled in the total function 
        ch <- 2  // this gets pushed and waits until it is pulled in the total function 
        ch <- 3  // this gets pushed and waits until it is pulled in the total function 
        close(ch)       // this will end the loop in the total function
        result := <-rch // waits for total to give the result
        fmt.Println("Total is ", result)
    } 
    

    Please help me understand how this would use any concurrency when it is completely synchronous?

    Maybe if you put the call to check in a go routine it would be a little more efficient, but still really makes no sense to me.

    评论

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改