我在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.") }
我不知道这是你以后的事情,但是你可以修改它,以满足你的需要.