如何从/ proc / pid / stat中获得应用程序的总CPU使用率?

我想知道如何计算一个进程的总CPU使用率。

如果我做cat /proc/ pid /stat ,我想相关的领域是( 取自lindevdoc.org ):

  1. 在用户代码中花费的CPU时间,以jiffies来衡量
  2. 在内核代码中花费的CPU时间,以jiffies来衡量
  3. 在用户代码中花费的CPU时间,包括来自儿童的时间
  4. 在内核代码中花费的CPU时间,包括来自儿童的时间

那么总共花费14到17场的总时间呢?

制备

要计算特定进程的CPU使用率,您需要以下内容:

  1. /proc/uptime
    • 系统正常运行时间(秒)
  2. /proc/[PID]/stat
    • #14 utime – 在用户代码中花费的CPU时间,以时钟滴答度量
    • #15 stime – 在内核代码中花费的CPU时间,以时钟滴答度量
    • #16 cutime – 在用户代码中花费的等待儿童的 CPU时间(以时钟周期为单位
    • #17 cstime – 在内核代码中花费的等待儿童的 CPU时间(以时钟周期为单位
    • #22 starttime – 进程开始的时间,以时钟滴答度量
  3. 赫兹(每秒的时钟滴答数)。
    • 在大多数情况下, getconf CLK_TCK可用于返回时钟滴答的数量。
    • sysconf(_SC_CLK_TCK) C函数调用也可以用来返回赫兹值。

计算

首先我们确定这个过程花费的总时间:

 total_time = utime + stime 

我们还必须决定是否要包括儿童stream程的时间。 如果我们这样做,那么我们将这些值添加到total_time

 total_time = total_time + cutime + cstime 

接下来,我们将获得自启动过程开始以秒计的总时间:

 seconds = uptime - (starttime / Hertz) 

最后我们计算CPU使用率:

 cpu_usage = 100 * ((total_time / Hertz) / seconds) 

也可以看看

顶部和PS不显示相同的CPU结果

如何在Linux中获得总CPU使用率(c ++)

计算Linux中进程的CPU使用率

是的,你可以这样说。 您可以使用公式将这些值转换为秒数:

  sec = jiffies / HZ ; here - HZ = number of ticks per second 

HZ值是可configuration的 – 在内核configuration时完成。

如果需要计算一个进程在过去10秒内使用了多lessCPU

  1. 在jiffies => t1 starttime(22)jiffies => s1中获得total_time(13 + 14)

– 延迟10秒

jiffies中的total_time(13 + 14)=> t2 jiffies中的starttime(22)=> s2

t2-t1 * 100 / s2 – s1不会给%?

这是另一种方式,我得到我的应用程序的CPU使用率。 我在Android中做了这个,并且调用了一个内核的顶级调用,并且使用什么顶级的返回来获得你的应用程序PID的CPU使用率。

 public void myWonderfulApp() { // Some wonderfully written code here Integer lMyProcessID = android.os.Process.myPid(); int lMyCPUUsage = getAppCPUUsage( lMyProcessID ); // More magic } // Alternate way that I switched to. I found the first version was slower // this version only returns a single line for the app, so far less parsing // and processing. public static float getTotalCPUUsage2() { try { // read global stats file for total CPU BufferedReader reader = new BufferedReader(new FileReader("/proc/stat")); String[] sa = reader.readLine().split("[ ]+", 9); long work = Long.parseLong(sa[1]) + Long.parseLong(sa[2]) + Long.parseLong(sa[3]); long total = work + Long.parseLong(sa[4]) + Long.parseLong(sa[5]) + Long.parseLong(sa[6]) + Long.parseLong(sa[7]); reader.close(); // calculate and convert to percentage return restrictPercentage(work * 100 / (float) total); } catch (Exception ex) { Logger.e(Constants.TAG, "Unable to get Total CPU usage"); } // if there was an issue, just return 0 return 0; } // This is an alternate way, but it takes the entire output of // top, so there is a fair bit of parsing. public static int getAppCPUUsage( Integer aAppPID) { int lReturn = 0; // make sure a valid pid was passed if ( null == aAppPID && aAppPID > 0) { return lReturn; } try { // Make a call to top so we have all the processes CPU Process lTopProcess = Runtime.getRuntime().exec("top"); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(lTopProcess.getInputStream())); String lLine; // While we have stuff to read and we have not found our PID, process the lines while ( (lLine = bufferedReader.readLine()) != null ) { // Split on 4, the CPU % is the 3rd field . // NOTE: We trim because sometimes we had the first field in the split be a "". String[] lSplit = lLine.trim().split("[ ]+", 4); // Don't even bother if we don't have at least the 4 if ( lSplit.length > 3 ) { // Make sure we can handle if we can't parse the int try { // On the line that is our process, field 0 is a PID Integer lCurrentPID = Integer.parseInt(lSplit[0]); // Did we find our process? if (aAppPID.equals(lCurrentPID)) { // This is us, strip off the % and return it String lCPU = lSplit[2].replace("%", ""); lReturn = Integer.parseInt(lCPU); break; } } catch( NumberFormatException e ) { // No op. We expect this when it's not a PID line } } } bufferedReader.close(); lTopProcess.destroy(); // Cleanup the process, otherwise you make a nice hand warmer out of your device } catch( IOException ex ) { // Log bad stuff happened } catch (Exception ex) { // Log bad stuff happened } // if there was an issue, just return 0 return lReturn; } 

这是你要找的东西:

 //USER_HZ detection, from openssl code #ifndef HZ # if defined(_SC_CLK_TCK) \ && (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000) # define HZ ((double)sysconf(_SC_CLK_TCK)) # else # ifndef CLK_TCK # ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ # define HZ 100.0 # else /* _BSD_CLK_TCK_ */ # define HZ ((double)_BSD_CLK_TCK_) # endif # else /* CLK_TCK */ # define HZ ((double)CLK_TCK) # endif # endif #endif 

这段代码实际上来自cpulimit ,但使用openssl片段。