Reputation: 333
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?
Upvotes: 1
Views: 2880
Reputation: 760
Yes, the parent needs to wait for the CPU time of the children to be added in (see manual entry for getrusage
link). Also see this answer for more details.
Upvotes: 1