sky*_*yde 9 performance multithreading scalability go
我在GO中重写一个旧系统,在旧系统中我测量系统负载平均值,以了解我是否应该增加线程池中的线程数.
在go中,人们不使用线程池或goroutine池,因为启动goroutine非常便宜.但仍然运行太多goroutine效率低,只是足以使cpu使用率接近100%
因此,有没有办法知道有多少goroutine准备运行(未阻止)但当前没有运行.或者有没有办法获得计划的runnable goroutine"运行队列"的数量.
Int*_*net 10
要打印"所有当前goroutine的堆栈跟踪",请使用:
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
Run Code Online (Sandbox Code Playgroud)
要打印"导致阻塞同步原语的堆栈跟踪",请使用:
pprof.Lookup("block").WriteTo(os.Stdout, 1)
Run Code Online (Sandbox Code Playgroud)
您可以将它们与运行时包中的函数结合起来,runtime.NumGoroutine以获得一些基本的报告.
这个例子故意创建了许多被阻止的goroutine并等待它们完成.它每5秒打印block一次pprof配置文件的输出,以及仍然存在的goroutine的数量:
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.")
}
Run Code Online (Sandbox Code Playgroud)
我不确定这是你所追求的,但你可以修改它以满足你的需要.
| 归档时间: |
|
| 查看次数: |
846 次 |
| 最近记录: |