Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate CPU utilization of a process & all its child processes in Linux?

I want to know the CPU utilization of a process and all the child processes, for a fixed period of time, in Linux.

To be more specific, here is my use-case:

There is a process which waits for a request from the user to execute the programs. To execute the programs, this process invokes child processes (maximum limit of 5 at a time) & each of this child process executes 1 of these submitted programs (let's say user submitted 15 programs at once). So, if user submits 15 programs, then 3 batches of 5 child processes each will run. Child processes are killed as soon as they finish their execution of the program.

I want to know about % CPU Utilization for the parent process and all its child process during the execution of those 15 programs.

Is there any simple way to do this using top or another command? (Or any tool i should attach to the parent process.)

like image 384
user1522820 Avatar asked Oct 13 '12 07:10

user1522820


3 Answers

And of course you can do it in hardcore-way using good old C

find_cpu.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MAX_CHILDREN 100

/**
 *  System command execution output
 *    @param <char> command - system command to execute
 *    @returb <char> execution output
 */
char *system_output (const char *command)
{
  FILE *pipe;
  static char out[1000];
  pipe = popen (command, "r");
  fgets (out, sizeof(out), pipe);
  pclose (pipe);
  return out;
}

/**
 *  Finding all process's children
 *    @param <Int> - process ID 
 *    @param <Int> - array of childs
 */
void find_children (int pid, int children[])
{
  char empty_command[] = "/bin/ps h -o pid --ppid ";
  char pid_string[5];

  snprintf(pid_string, 5, "%d", pid);

  char *command = (char*) malloc(strlen(empty_command) + strlen(pid_string) + 1);
  sprintf(command, "%s%s", empty_command, pid_string);

  FILE *fp = popen(command, "r");

  int child_pid, i = 1;
  while (fscanf(fp, "%i", &child_pid) != EOF)
  {
    children[i] = child_pid;
    i++;
  }
}

/**
 *  Parsign `ps` command output
 *    @param <char> out - ps command output
 *    @return <int> cpu utilization
 */
float parse_cpu_utilization (const char *out)
{
  float cpu;
  sscanf (out, "%f", &cpu);
  return cpu;
}


int main(void)
{
  unsigned pid = 1;

  // getting array with process children
  int process_children[MAX_CHILDREN] = { 0 };
  process_children[0] = pid; // parent PID as first element
  find_children(pid, process_children);

  // calculating summary processor utilization
  unsigned i;
  float common_cpu_usage = 0.0;
  for (i = 0; i < sizeof(process_children)/sizeof(int); ++i) 
  {
    if (process_children[i] > 0) 
    {
      char *command = (char*)malloc(1000);
      sprintf (command, "/bin/ps -p %i -o 'pcpu' --no-headers", process_children[i]);
      common_cpu_usage += parse_cpu_utilization(system_output(command));
    }
  }
  printf("%f\n", common_cpu_usage);
  return 0;
}

Compile:

gcc -Wall -pedantic --std=gnu99 find_cpu.c

Enjoy!

like image 197
Sergey Gerasimov Avatar answered Nov 16 '22 05:11

Sergey Gerasimov


You can find this information in /proc/PID/stat where PID is your parent process's process ID. Assuming that the parent process waits for its children then the total CPU usage can be calculated from utime, stime, cutime and cstime:

utime %lu

Amount of time that this process has been scheduled in user mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK). This includes guest time, guest_time (time spent running a virtual CPU, see below), so that applications that are not aware of the guest time field do not lose that time from their calculations.

stime %lu

Amount of time that this process has been scheduled in kernel mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK).

cutime %ld

Amount of time that this process's waited-for children have been scheduled in user mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK). (See also times(2).) This includes guest time, cguest_time (time spent running a virtual CPU, see below).

cstime %ld

Amount of time that this process's waited-for children have been scheduled in kernel mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK).

See proc(5) manpage for details.

like image 37
Adam Zalcman Avatar answered Nov 16 '22 05:11

Adam Zalcman


Might not be the exact command. But you can do something like below to get cpu usage of various process and add it.

#ps -C sendmail,firefox -o pcpu= | awk '{s+=$1} END {print s}'

/proc/[pid]/stat Status information about the process. This is used by ps and made into human readable form.

Another way is to use cgroups and use cpuacct.

http://www.kernel.org/doc/Documentation/cgroups/cpuacct.txt

https://access.redhat.com/knowledge/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/sec-cpuacct.html

like image 2
Ranjith Ruban Avatar answered Nov 16 '22 05:11

Ranjith Ruban