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)
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.
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:
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
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.
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.