多线程 – 使用GO时如何测量系统过载

我在GO中重写一个旧系统,而在旧系统中,我正在测量系统负载平均值,以了解是否应该增加线程池中的线程数.

在人们没有使用线程池或goroutine池,因为启动goroutine是非常便宜的.
但仍然运行太多的goroutine效率较低,那么足以使cpu使用率接近100%

因此,有没有办法知道有多少goroutine准备运行(未被阻止)但不是当前正在运行.或者有一种方法获取预定的可运行的goroutine“运行队列”的数量.

解决方法

查看 runtime/pprof package.

要打印“所有当前goroutines的堆栈跟踪”,请使用:

pprof.Lookup("goroutine").Writeto(os.Stdout,1)

要打印“导致同步原语阻塞的堆栈跟踪”,请使用:

pprof.Lookup("block").Writeto(os.Stdout,1)

您可以将这些与runtime package中的功能(如runtime.NumGoroutine)进行组合,以获得一些基本报告.

此示例故意创建了许多阻止的goroutines并等待他们完成.每5秒打印块pprof配置文件输出以及仍然存在的goroutines数量

package main

import (
    "fmt"
    "math/rand"
    "os"
    "runtime"
    "runtime/pprof"
    "strconv"
    "sync"
    "time"
)

var (
    wg sync.WaitGroup
    m  sync.Mutex
)

func randWait() {
    defer wg.Done()
    m.Lock()
    defer m.Unlock()
    interval,err := time.ParseDuration(strconv.Itoa(rand.Intn(499)+1) + "ms")
    if err != nil {
        fmt.Errorf("%s\n",err)
    }
    time.Sleep(interval)
    return
}

func blockStats() {
    for {
        pprof.Lookup("block").Writeto(os.Stdout,1)
        fmt.Println("# Goroutines:",runtime.NumGoroutine())
        time.Sleep(5 * time.Second)
    }
}

func main() {
    rand.Seed(time.Now().Unix())
    runtime.SetBlockProfileRate(1)
    fmt.Println("Running...")
    for i := 0; i < 100; i++ {
        wg.Add(1)
        go randWait()
    }
    go blockStats()
    wg.Wait()
    fmt.Println("Finished.")
}

我不知道这是你以后的事情,但是你可以修改它,以满足你的需要.

Playground

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...