Golang异步和CPU使用率

时间:2018-04-15 20:04:17

标签: go concurrency cpu

我正在学习Go并发,我的期望是使用goroutines和channel应该增加并发性。该程序需要几毫秒才能完成。但是随着负载的增加,执行时间不断增加,尽管有大量的CPU空闲。

我正在向下面的程序发送1200 QPS / TPS来分析响应时间的请求,我发现程序的总体执行时间会随着时间的推移而增加。此外,CPU使用率约为3-6%。

当我将QPS增加到100,000时,程序的执行时间增加到秒(从最初的毫秒开始)。但CPU使用率仍为8-9%。

那么为什么程序不能使用其他90-94%的可用CPU并更快地完成程序的执行呢?

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

答案 0 :(得分:2)

我不确定你在这个小服务器上想要做什么。

1)您正在创建一个WaitGroup并向其添加1,调用匿名go例程,并在main中等待,这不会做任何事情,然后将您的main移动到匿名函数。

2)让我们看看你在checktotal函数中做了些什么:

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

请帮助我理解当它完全同步时如何使用任何并发?

也许如果你把check的电话放在一个常规程序中,它会更有效率,但对我来说仍然没有意义。