如何从C中通过PID在Linux中计算进程的CPU使用率?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1420426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:41:34  来源:igfitidea点击:

How to calculate the CPU usage of a process by PID in Linux from C?

clinuxcpu-usage

提问by codingfreak

I want to programmatically [in C] calculate CPU usage % for a given process ID in Linux.

我想以编程方式 [in C] 计算 Linux 中给定进程 ID 的 CPU 使用率百分比。

How can we get the realtime CPU usage % for a given process?

我们如何获得给定进程的实时 CPU 使用率百分比?

To make it further clear:

为了进一步明确:

  • I should be able to determine the CPU usage for the provided processid or process.
  • The process need not be the child process.
  • I want the solution in 'C' language.
  • 我应该能够确定提供的进程 ID 或进程的 CPU 使用率。
  • 该进程不必是子进程。
  • 我想要'C'语言的解决方案。

采纳答案by caf

You need to parse out the data from /proc/<PID>/stat. These are the first few fields (from Documentation/filesystems/proc.txtin your kernel source):

您需要从/proc/<PID>/stat. 这些是前几个字段(来自Documentation/filesystems/proc.txt内核源代码):

Table 1-3: Contents of the stat files (as of 2.6.22-rc3)
..............................................................................
 Field          Content
  pid           process id
  tcomm         filename of the executable
  state         state (R is running, S is sleeping, D is sleeping in an
                uninterruptible wait, Z is zombie, T is traced or stopped)
  ppid          process id of the parent process
  pgrp          pgrp of the process
  sid           session id
  tty_nr        tty the process uses
  tty_pgrp      pgrp of the tty
  flags         task flags
  min_flt       number of minor faults
  cmin_flt      number of minor faults with child's
  maj_flt       number of major faults
  cmaj_flt      number of major faults with child's
  utime         user mode jiffies
  stime         kernel mode jiffies
  cutime        user mode jiffies with child's
  cstime        kernel mode jiffies with child's

You're probably after utimeand/or stime. You'll also need to read the cpuline from /proc/stat, which looks like:

你可能在utime和/或stime. 您还需要阅读cpu来自的行/proc/stat,如下所示:

cpu  192369 7119 480152 122044337 14142 9937 26747 0 0

This tells you the cumulative CPU time that's been used in various categories, in units of jiffies. You need to take the sum of the values on this line to get a time_totalmeasure.

这会告诉您在各种类别中使用的累积 CPU 时间,以 jiffies 为单位。您需要对这条线上的值求和才能得到一个time_total度量。

Read both utimeand stimefor the process you're interested in, and read time_totalfrom /proc/stat. Then sleep for a second or so, and read them all again. You can now calculate the CPU usage of the process over the sampling time, with:

阅读utime和阅读stime您感兴趣的过程,并time_total/proc/stat. 然后睡一秒钟左右,然后再读一遍。您现在可以通过以下方式计算进程在采样时间内的 CPU 使用率:

user_util = 100 * (utime_after - utime_before) / (time_total_after - time_total_before);
sys_util = 100 * (stime_after - stime_before) / (time_total_after - time_total_before);

Make sense?

有道理?

回答by vpram86

getrusage()can help you in determining the usage of current process or its child

getrusage()可以帮助您确定当前进程或其子进程的使用情况

Update:I can't remember an API. But all details will be in /proc/PID/stat, so if we could parse it, we can get the percentage.

更新:我不记得 API。但是所有细节都在/proc/ PID/stat中,所以如果我们可以解析它,我们就可以得到百分比。

EDIT:Since CPU % is not straight forward to calculate, You could use sampling kind of stuff here. Read ctime and utime for a PID at a point in time and read the same values again after 1 sec. Find the difference and divide by hundred. You will get utilization for that process for past one second.

编辑:由于 CPU % 不是直接计算的,您可以在这里使用采样类型的东西。在某个时间点读取 PID 的 ctime 和 utime,并在 1 秒后再次读取相同的值。找出差异并除以百。您将在过去一秒钟内获得该过程的利用率。

(might get more complex if there are many processors)

(如果有很多处理器,可能会变得更复杂)

回答by Andre Miller

You can read the manpage for procfor more detail, but in summary you can read /proc/[number]/stat to get the information about a process. This is also used by the 'ps' command.

您可以阅读proc联机帮助页以获取更多详细信息,但总的来说,您可以阅读 /proc/[number]/stat 以获取有关进程的信息。这也被“ps”命令使用。

All the fields and their scanf format specifiers are documented in the proc manpage.

所有字段及其 scanf 格式说明符都记录在proc 手册页中

Here are some of the information from the manpagecopied (it is quite long):

以下是复制的联机帮助页中的一些信息(很长):

          pid %d The process ID.

          comm %s
                 The  filename of the executable, in parentheses.  This is
                 visible whether or not the executable is swapped out.

          state %c
                 One character from the string "RSDZTW" where  R  is  runa
                 ning,  S is sleeping in an interruptible wait, D is waita
                 ing in uninterruptible disk sleep,  Z  is  zombie,  T  is
                 traced or stopped (on a signal), and W is paging.

          ppid %d
                 The PID of the parent.

          pgrp %d
                 The process group ID of the process.

          session %d
                 The session ID of the process.

          tty_nr %d
                 The tty the process uses.

          tpgid %d
                 The  process group ID of the process which currently owns
                 the tty that the process is connected to.

回答by James Anderson

Take a look at the "pidstat" command, sounds like exactly what you require.

看看“pidstat”命令,听起来正是您所需要的。

回答by fho

I wrote two little C function based on cafs answer to calculate the user+kernel cpu usage of of an process: https://github.com/fho/code_snippets/blob/master/c/getusage.c

我根据cafs answer写了两个小C函数来计算一个进程的用户+内核cpu使用情况:https: //github.com/fho/code_snippets/blob/master/c/getusage.c

回答by Lifeguard

Install psacctor acctpackage. Then use the sacommand to display CPU time used for various commands. sa man page

安装psacctacct打包。然后使用该sa命令显示用于各种命令的 CPU 时间。 sa手册页

A nice howtofrom the nixCraft site.

一个不错的HOWTO从nixCraft网站。

回答by Mohan Ram

This is my solution...

这是我的解决方案...

/*
this program is looking for CPU,Memory,Procs also u can look glibtop header there was a lot of usefull function have fun..
systeminfo.c
*/
#include <stdio.h>
#include <glibtop.h>
#include <glibtop/cpu.h>
#include <glibtop/mem.h>
#include <glibtop/proclist.h>



int main(){

glibtop_init();

glibtop_cpu cpu;
glibtop_mem memory;
glibtop_proclist proclist;

glibtop_get_cpu (&cpu);
glibtop_get_mem(&memory);


printf("CPU TYPE INFORMATIONS \n\n"
"Cpu Total : %ld \n"
"Cpu User : %ld \n"
"Cpu Nice : %ld \n"
"Cpu Sys : %ld \n"
"Cpu Idle : %ld \n"
"Cpu Frequences : %ld \n",
(unsigned long)cpu.total,
(unsigned long)cpu.user,
(unsigned long)cpu.nice,
(unsigned long)cpu.sys,
(unsigned long)cpu.idle,
(unsigned long)cpu.frequency);

printf("\nMEMORY USING\n\n"
"Memory Total : %ld MB\n"
"Memory Used : %ld MB\n"
"Memory Free : %ld MB\n"
"Memory Buffered : %ld MB\n"
"Memory Cached : %ld MB\n"
"Memory user : %ld MB\n"
"Memory Locked : %ld MB\n",
(unsigned long)memory.total/(1024*1024),
(unsigned long)memory.used/(1024*1024),
(unsigned long)memory.free/(1024*1024),
(unsigned long)memory.shared/(1024*1024),
(unsigned long)memory.buffer/(1024*1024),
(unsigned long)memory.cached/(1024*1024),
(unsigned long)memory.user/(1024*1024),
(unsigned long)memory.locked/(1024*1024));

int which,arg;
glibtop_get_proclist(&proclist,which,arg);
printf("%ld\n%ld\n%ld\n",
(unsigned long)proclist.number,
(unsigned long)proclist.total,
(unsigned long)proclist.size);
return 0;
}

makefile is
CC=gcc
CFLAGS=-Wall -g
CLIBS=-lgtop-2.0 -lgtop_sysdeps-2.0 -lgtop_common-2.0

cpuinfo:cpu.c
$(CC) $(CFLAGS) systeminfo.c -o systeminfo $(CLIBS)
clean:
rm -f systeminfo

回答by zizzu

Easy step to step for beginners like me:

像我这样的初学者的简单步骤:

  1. Read the first line of /proc/statto get total_cpu_usage1.
  1. 阅读 的第一行/proc/stat以获取total_cpu_usage1.
    sscanf(line,"%*s %llu %llu %llu %llu",&user,&nice,&system,&idle);
    total_cpu_usage1 = user + nice + system + idle;
  1. Read /proc/pid/statwhere pidis the PID of the process you want to know the CPU usage, like this:
  1. 读取你想知道CPU使用率的进程的PID/proc/pid/stat在哪里pid,像这样:
    sscanf(line,
    "%*d %*s %*c %*d" //pid,command,state,ppid

    "%*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu"

    "%lu %lu" //usertime,systemtime

    "%*ld %*ld %*ld %*ld %*ld %*ld %*llu"

    "%*lu", //virtual memory size in bytes
    ....)
  1. Now sum usertimeand systemtimeand get proc_times1
  2. Now wait 1 second or more
  3. Do it again, and get total_cpu_usage2and proc_times2
  1. 现在总结usertimesystemtime和GETproc_times1
  2. 现在等待 1 秒或更长时间
  3. 再做一次,得到total_cpu_usage2proc_times2

The formula is:

公式为:

(number of processors) * (proc_times2 - proc_times1) * 100 / (float) (total_cpu_usage2 - total_cpu_usage1)

You can get the amount of CPU's from /proc/cpuinfo.

您可以从/proc/cpuinfo.

回答by user3288728

I think it's worth looking at GNU "time" command source code. timeIt outputs user/system cpu time along with real elapsed time. It calls wait3/wait4 system call (if available) and otherwise it calls times system call. wait* system call returns a "rusage" struct variable and times system call returns "tms". Also, you can have a look at getrusage system call which also return very interesting timing information. time

我认为值得查看 GNU“时间”命令源代码。time它输出用户/系统 CPU 时间以及实际经过的时间。它调用wait3/wait4 系统调用(如果可用),否则调用times 系统调用。wait* 系统调用返回一个“rusage”结构变量,times 系统调用返回“tms”。此外,您可以查看 getrusage 系统调用,它也返回非常有趣的计时信息。时间

回答by ensonic

Instead of parsing this from proc, one can use functions like getrusage() or clock_gettime() and calculate the cpu usage as a ratio or wallclock time and time the process/thread used on the cpu.

可以使用 getrusage() 或 clock_gettime() 等函数,而不是从 proc 解析它,并将 CPU 使用率计算为比率或挂钟时间和 CPU 上使用的进程/线程的时间。