101

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

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

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.
Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
codingfreak
  • 4,467
  • 11
  • 48
  • 60

13 Answers13

166

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

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 utime and/or stime. You'll also need to read the cpu line from /proc/stat, which looks like:

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_total measure.

Read both utime and stime for the process you're interested in, and read time_total from /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:

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?

caf
  • 233,326
  • 40
  • 323
  • 462
  • @caf - I am really a newbie to this jiffy stuff ... sorry not able to understand what your saying .... – codingfreak Sep 15 '09 at 04:51
  • 14
    A "jiffy" is a unit of CPU time. Exactly what it corresponds to in wall-clock time depends on the architecture and how your kernel is configured, but the important thing is that `/proc/stat` tells you how many jiffies the CPU has executed in total, and `/proc//stat` tells you how many jiffies have been executed by a single process. – caf Sep 15 '09 at 06:21
  • @caf - I am trying to learn the jiffy stuff .. meanwhile can you write down small code where u calculate the CPU usage of a process ?? – codingfreak Sep 15 '09 at 08:40
  • @codingfreak - As caf says, you do not need to learn what jiffy really is, just follow the given formula. – Emre Yazici Oct 17 '10 at 11:16
  • Any idea where these fields are documented in kernel 3.0? the documentation proc.txt does not seem up to date with what I see in the proc. – dbbd Jan 22 '12 at 14:23
  • What is /proc//stat exactly? – fIwJlxSzApHEZIl May 06 '12 at 23:38
  • 1
    @advocate: It's a pseudo-file which implements an interface to retrieve process execution statistics from the kernel. – caf May 07 '12 at 01:49
  • 6
    To people seeking for more information about the fields: ``man proc`` is your friend (search for ``/proc/[pid]/stat``) – redShadow Jun 28 '13 at 23:24
  • 1
    Comparing caf's solution with the one provided by zizzu (below), caf's solution gives system and user times separately but doesn't multiply either of these values with the number of CPUs. Shouldn't it be doing that? – linuxfan Mar 21 '16 at 20:40
  • 1
    @linuxfan: It depends on whether you want the % of the total CPU time available to the system or the % of a single CPU (which may give a figure greater than 100% for a multithreaded process). This answer gives the former. – caf Mar 21 '16 at 23:18
  • @caf Thanks for the clarification. – linuxfan Mar 21 '16 at 23:50
  • 2
    I'd like to share a little example program that I created based on this answer: https://github.com/scaidermern/top-processes. Feel free to make us of it, it is licensed under CC0. – scai Aug 14 '16 at 11:59
  • @caf I have a problem, and that is that the values for `utime` and `stime` that I get from the file `/proc/[pid]/stat` are equal to 0 even if I add sleep to the process before getting these value. I am currently blocked, does someone have an idea why is that? – Bionix1441 Sep 20 '17 at 14:08
  • @Bionix1441: These days a jiffy is a very long unit of CPU time - on the order of 10 million cycles. `sleep()` doesn't use any CPU time, neither user nor system, so the problem is likely hat your target process just hasn't used up any appreciable amount of CPU time yet. You need to put some kind of busy calculating loop in if you want to use CPU time. – caf Sep 20 '17 at 23:25
  • Downvoted. This doesn't answer the OPs question (I want the solution in 'C' language.) – Graham Jan 09 '18 at 15:44
  • 2
    Apparently the OP disagreed. The key insight here is to use the `/proc` pseudo-file system: the teaching of standard C file system access functions like `fopen()` and `scanf()` is beside the point. – caf Jan 11 '18 at 00:33
  • Am I right in thinking this will give the % of CPU relative to what has been used? Meaning, if I have a CPU with variable clock speed, say 600 MHz, 1.2 GHz, and 2.4 GHz, and the CPU has been running at 600 MHz for the duration that I've been recording data, this could show that I'm using 100% CPU even though it's only 25% of the maximum CPU at full speed? – Rusty Lemur Mar 20 '19 at 02:10
  • @RustyLemur: Correct, it's the proportion used of the CPU time that was available. Doubling the clock speed doesn't mean it would have used half the time to do the same processing anyway - any time spent waiting for memory access counts as on-CPU time and that doesn't get faster as you increase the clock speed. – caf Mar 20 '19 at 02:54
  • I tried this solution bit in some cases `(time_total_after - time_total_before) < (utime_after - utime_before) + (stime_after - stime_before)`. How is it possible? Am I doing something wrong? – yrHeTateJlb Apr 26 '19 at 09:46
11

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

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.

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.

(might get more complex if there are many processors)

vpram86
  • 5,860
  • 4
  • 28
  • 40
  • 2
    How does getrusage() system call help me in calculating CPU usage of a process ?? – codingfreak Sep 14 '09 at 09:06
  • @codingfreak. i misunderstood the question. Now after u updated it, clear. – vpram86 Sep 14 '09 at 09:22
  • 1
    @Aviator CPU % = (processusertime + processkerneltime)/(CPUusertime+CPUkerneltime) How can I get the values for "processusertime" and so on. ??? I see different values down in "/proc/PID/stat" file. So which one corresponds to which value ?? – codingfreak Sep 14 '09 at 09:32
  • @codingfreak:CPU time is difficult to calculate. U need to loop through all PID stats i guess (though not sure) – vpram86 Sep 14 '09 at 10:08
  • @Aviator there would be some way or other to do it ... since even applications like top should calculate the CPU usage to show in their output – codingfreak Sep 14 '09 at 10:14
  • @codingfreak: Yes. There should be. I think they all will be using /proc/PIDs/stat internally. I can think of no other place they can get so much data! – vpram86 Sep 14 '09 at 10:18
8

Easy step to step for beginners like me:

  1. Read the first line of /proc/stat to get 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/stat where pid is the PID of the process you want to know the CPU usage, like this:
    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 usertime and systemtime and get proc_times1
  2. Now wait 1 second or more
  3. Do it again, and get total_cpu_usage2 and proc_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.

Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
zizzu
  • 81
  • 1
  • 1
  • 4
    Your solution is good but to get the number of CPUs, make it simpler. Include this guy `#include ` and call this method `int nb = sysconf(_SC_NPROCESSORS_ONLN);` – David Guyon Jun 03 '14 at 08:01
  • 4
    I do not understand why multiply by the (number of processors), assuming delta(proc_times) is for the core on which it executed. Without multiplying by the factor or CPUs, it should be correct. – JayabalanAaron Nov 27 '17 at 11:53
  • @JayabalanAaron: Linux measures the CPU percentage to a 0 - (100 * #cores) % scale. This is the so-called 'Irix mode'. Unix systems, on the other hand use a 0-100% scale (the Solaris mode) – drgnfr Jun 05 '22 at 22:10
6

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

fho
  • 470
  • 5
  • 12
  • is there is a compiled version of it as It gives me error while compiling and also how can I use it? – Medhat Nov 13 '14 at 14:19
  • I does not have a main() function therefore it's not a "standalone" program than you can compile and execute. You would have to write a main() function that does some things with the functions of getusage.c – fho Nov 13 '14 at 18:07
  • It's not really using C functions. Just using an arbitrary language to parse command output. – Graham Jan 09 '18 at 15:47
4

You can read the manpage for proc for 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.

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

Here are some of the information from the manpage copied (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  runâ
                 ning,  S is sleeping in an interruptible wait, D is waitâ
                 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.
Andre Miller
  • 15,255
  • 6
  • 55
  • 53
  • “CPU usage” and “current state” are like location and velocity. If you know one you can’t know the other. CPU usage depends on a duration so you have to check yourself how often your process is in the “R” state. – Bombe Sep 14 '09 at 09:45
  • Hmm, good question, I always just assumed it would be there! Presumably you should be able to calculate it from these variables – Andre Miller Sep 14 '09 at 09:51
  • If you check the output of top command you can see CPU usage .... but I am not intrested in greping through top output to calculate CPU usage ..... – codingfreak Sep 14 '09 at 09:54
  • @codingfreak: `ps aux` is better :) – vpram86 Sep 14 '09 at 09:55
  • @Aviator - I have already told u to forget about grepping the output of a shell command to determine the CPU USAGE % – codingfreak Sep 14 '09 at 10:13
  • @codingfreak : :) I understand. Just told! :) – vpram86 Sep 14 '09 at 10:17
  • You could always go check the source code of top to see how they did it. I'm guessing they also look at /proc//stat and use a a calculation to find the utilization over time. – Andre Miller Sep 14 '09 at 19:08
2

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

James Anderson
  • 27,109
  • 7
  • 50
  • 78
2

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
Mohan Ram
  • 8,345
  • 25
  • 81
  • 130
1

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.

ensonic
  • 3,304
  • 20
  • 31
1

When you want monitor specified process, usually it is done by scripting. Here is perl example. This put percents as the same way as top, scalling it to one CPU. Then when some process is active working with 2 threads, cpu usage can be more than 100%. Specially look how cpu cores are counted :D then let me show my example:

#!/usr/bin/perl

my $pid=1234; #insert here monitored process PID

#returns current process time counters or single undef if unavailable
#returns:  1. process counter  , 2. system counter , 3. total system cpu cores
sub GetCurrentLoads {
    my $pid=shift;
    my $fh;
    my $line;
    open $fh,'<',"/proc/$pid/stat" or return undef;
    $line=<$fh>;
    close $fh;
    return undef unless $line=~/^\d+ \([^)]+\) \S \d+ \d+ \d+ \d+ -?\d+ \d+ \d+ \d+ \d+ \d+ (\d+) (\d+)/;
    my $TimeApp=$1+$2;
    my $TimeSystem=0;
    my $CpuCount=0;
    open $fh,'<',"/proc/stat" or return undef;
    while (defined($line=<$fh>)) {
        if ($line=~/^cpu\s/) {
            foreach my $nr ($line=~/\d+/g) { $TimeSystem+=$nr; };
            next;
        };
        $CpuCount++ if $line=~/^cpu\d/;
    }
    close $fh;
    return undef if $TimeSystem==0;
    return $TimeApp,$TimeSystem,$CpuCount;
}

my ($currApp,$currSys,$lastApp,$lastSys,$cores);
while () {
    ($currApp,$currSys,$cores)=GetCurrentLoads($pid);
    printf "Load is: %5.1f\%\n",($currApp-$lastApp)/($currSys-$lastSys)*$cores*100 if defined $currApp and defined $lastApp and defined $currSys and defined $lastSys;
    ($lastApp,$lastSys)=($currApp,$currSys);
    sleep 1;
}

I hope it will help you in any monitoring. Of course you should use scanf or other C functions for converting any perl regexpes I've used to C source. Of course 1 second for sleeping is not mandatory. you can use any time. effect is, you will get averrage load on specfied time period. When you will use it for monitoring, of course last values you should put outside. It is needed, because monitoring usually calls scripts periodically, and script should finish his work asap.

Znik
  • 1,047
  • 12
  • 17
0

I think it's worth looking at GNU "time" command source code. time It 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

0

Install psacct or acct package. Then use the sa command to display CPU time used for various commands. sa man page

A nice howto from the nixCraft site.

Lifeguard
  • 179
  • 3
0

Use strace found the CPU usage need to be calculated by a time period:

# top -b -n 1 -p 3889
top - 16:46:37 up  1:04,  3 users,  load average: 0.00, 0.01, 0.02
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  5594496 total,  5158284 free,   232132 used,   204080 buff/cache
KiB Swap:  3309564 total,  3309564 free,        0 used.  5113756 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 3889 root      20   0  162016   2220   1544 S   0.0  0.0   0:05.77 top
# strace top -b -n 1 -p 3889
.
.
.
stat("/proc/3889", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/3889/stat", O_RDONLY)       = 7
read(7, "3889 (top) S 3854 3889 3854 3481"..., 1024) = 342
.
.
.

nanosleep({0, 150000000}, NULL)         = 0
.
.
.
stat("/proc/3889", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/3889/stat", O_RDONLY)       = 7
read(7, "3889 (top) S 3854 3889 3854 3481"..., 1024) = 342
.
.
.
Jinming Lv
  • 93
  • 1
  • 5
0

htop -p <pid-of-process> . It will list all the cpus and their utilisation.

kushagra deep
  • 462
  • 6
  • 12