[Solved-6 Solutions] How to calculate the CPU usage of a process by PID in Linux from C - Linux Tutorial
Problem :
How to calculate the CPU usage of a process by PID in Linux from C ?
Solution 1:
Monitor specified process, usually it is done by scripting. 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%.
#!/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;
}
Solution 2:
The data from /proc/PID/stat
. These are the first few fields (from Documentation/filesystems/proc.txt in 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
To read the CPU line from /proc/stat
:
cpu 192369 7119 480152 122044337 14142 9937 26747 0 0
The cumulative CPU time is used to various categories. The sum of the values to get a time_total.
Read both utime and stime for the process and to read time_total from /proc/stat
. To calculate the CPU usage of the process over the sampling time:
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);
Solution 3:
getrusage()
is used to determining the usage of current process or its child
- To calculate CPU % is not in a straight forward.
- PID at a point in time to read ctime and utime the same values.
- To find the difference and divide by hundred.
Solution 4:
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;
read /proc/pid/stat
where pid used to know the cpu usage:
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
....)
Add the usertime and system time to get proc_times1. We want to get total_cpu_usage2 and proc_times2 do it same process.
The formula is:
(number of processors) * (proc_times2 - proc_times1) * 100 / (float) (total_cpu_usage2 - total_cpu_usage1)
To get the num of CPU's from /proc/cpuinfo
Solution 5:
Read /proc/[number]/stat
to get the information. This is also used by the 'ps' command. All the fields and their scanf format specifiers are documented in the proc manpage
.
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.
Solution 6:
"pidstat"
command is used to exactly to require.