shirou / gopsutil

psutil for golang
Other
10.5k stars 1.58k forks source link

process.Percent sometime return wrong value when have mary goroutines #1214

Open xiaoshi100086 opened 2 years ago

xiaoshi100086 commented 2 years ago

Describe the bug process.Percent sometime return wrong value when have mary goroutines. To Reproduce I write demo code.

package main

import (
    "fmt"
    "os"
    "time"

    "github.com/shirou/gopsutil/process"
)

const MaxPercent = 800 // the machine have 8 cpu

// print process cpu usage per second
func metric() {
    p, err := process.NewProcess(int32(os.Getpid()))
    if err != nil {
        panic(err)
    }
    var lastTicker = time.Now()
    ticker := time.NewTicker(time.Second)
    for range ticker.C {
        now := time.Now()

        percent, err := p.Percent(0)
        if err != nil {
            panic(err)
        }
        if percent > MaxPercent {
            fmt.Printf("process percent: %f, \tticker interval: %fs\n", percent, now.Sub(lastTicker).Seconds())
        }

        lastTicker = now
    }
}

func main() {
    for i := 0; i < 10000; i++ {
        go func() {
            for {
            }
        }()
    }
    go metric()
    <-make(chan struct{})
}

go.mod

module demo

go 1.15

require (
    github.com/shirou/gopsutil v3.21.11+incompatible
    github.com/tklauser/go-sysconf v0.3.9 // indirect
)

Expected behavior [A clear and concise description of what you expected to happen.] The print txt "process percent" should be <= 800, because the machine have 8 cpu.

But I got this:

process percent: 168871696.801113,      ticker interval: 33.316982s
process percent: 20228.992191,  ticker interval: 29.470608s
process percent: 225733353.254644,      ticker interval: 31.351190s
process percent: 208994766.209612,      ticker interval: 31.867065s

Environment (please complete the following information):

cat /etc/os-release

NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

uname -a

Linux hkqc-172_27_9_202-null 3.10.0-1062.12.1.el7.x86_64 #1 SMP Tue Feb 4 23:02:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Additional context [Cross-compiling? Paste the command you are using to cross-compile and the result of the corresponding go env]

shirou commented 2 years ago

Since the ticker interval in your code is 30sec, I think the load is too high and getting the time is too slow. Now I do not know how to solve this problem.