I have a C program that parses the /proc//stat directory to calculate the average CPU utilization over a period of 5 seconds:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define ITERATIONS 5
int main(int argc, char *argv[])
{
if (argc != 2) {
printf( "usage: %s <PID>\n", argv[0] );
return(-1);
}
long double a[4], b[4];
long double pidTime = 0.0;
long int clk;
int i;
FILE *fp;
char stat[1024];
clk = sysconf(_SC_CLK_TCK);
if (clk == -1) {
printf("Could not determine clock ticks per second");
return(-1);
}
char *pidPath = malloc(strlen("/proc/stat/")+strlen(argv[1])+1);
if (pidPath == NULL) {
printf("Could not allocate memory for str\n");
return(-1);
} else {
strcpy(pidPath, "/proc/");
strcat(pidPath, argv[1]);
strcat(pidPath, "/stat");
}
for(i = 0; i < ITERATIONS; i++)
{
fp = fopen(pidPath,"r");
if (fp == NULL) {
perror(pidPath);
return(-1);
} else {
fgets(stat, sizeof(stat), fp);
sscanf(stat,"%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %Lf %Lf %Lf %Lf %*ld %*ld %*ld %*ld %*llu",&a[0],&a[1],&a[2],&a[3]);
fclose(fp);
sleep(1);
}
fp = fopen(pidPath,"r");
if (fp == NULL) {
perror(pidPath);
return(-1);
} else {
fgets(stat, sizeof(stat), fp);
sscanf(stat,"%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %Lf %Lf %Lf %Lf %*ld %*ld %*ld %*ld %*llu",&b[0],&b[1],&b[2],&b[3]);
fclose(fp);
}
pidTime += (((b[0]+b[1]+b[2]+b[3]) - (a[0]+a[1]+a[2]+a[3])));
}
pidTime = (pidTime / (clk * ITERATIONS));
printf("pidCPU=%Lf\n", pidTime);
printf("%ld", clk);
free(pidPath);
return(0);
}
From what I understand the relevant fields in stat are:
int utime; /** user mode jiffies **/
int stime; /** kernel mode jiffies **/
int cutime; /** user mode jiffies with childs **/
int cstime; /** kernel mode jiffies with childs **/
For a single process, this works great, but when I have a process that forks, or is multithreaded, this breaks down. Do the cutime and cstime counters only work when the parent is waiting for the child processes? How can I calculate the total usage of the process tree rooted at PID?