微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

多线程 – 使用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

原文地址:https://www.jb51.cc/java/123503.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐