2012-10-13 225 views
7

Quiero saber la utilización de la CPU de un proceso y todos los procesos secundarios, durante un período de tiempo fijo, en Linux.Cómo calcular la utilización de CPU de un proceso y todos sus procesos secundarios en Linux?

Para ser más específicos, aquí está mi caso de uso:

No es un proceso que espera a una petición del usuario para ejecutar los programas. Para ejecutar los programas, este proceso invoca procesos secundarios (límite máximo de 5 a la vez) & cada uno de estos procesos secundarios ejecuta 1 de estos programas enviados (digamos que el usuario envió 15 programas a la vez). Entonces, si el usuario envía 15 programas, se ejecutarán 3 lotes de 5 procesos secundarios cada uno. Los procesos secundarios se eliminan tan pronto como finalicen su ejecución del programa.

Quiero saber acerca de% CPU Utilization para el proceso principal y todo su proceso secundario durante la ejecución de esos 15 programas.

¿Hay alguna manera simple de hacer esto usando la parte superior u otro comando? (O cualquier herramienta que deba adjuntar al proceso principal.)

Respuesta

8

Puede encontrar esta información en /proc/PID/stat donde PID es el ID de proceso de su proceso principal. Suponiendo que el proceso padre espera a que sus hijos, entonces el uso total de CPU puede calcularse a partir utime, stime, cutime y cstime:

utime% lu

Cantidad de tiempo que este proceso se ha programado en modo de usuario, medido en marcas de reloj (dividir por sysconf (_SC_CLK_TCK). Esto incluye tiempo de invitado, tiempo_usuario (tiempo dedicado a ejecutar una CPU virtual, ver a continuación), de modo que Las plicaciones que no conocen el campo de tiempo de invitado no pierden ese tiempo de sus cálculos.

stime% lu

Cantidad de tiempo que este proceso ha sido programada en el modo kernel, medido en ciclos de reloj (divide por sysconf (_SC_CLK_TCK).

cutime% ld

Cantidad de vez que los hijos esperados de este proceso han sido programados en modo de usuario, medido en ticks de reloj (divida por sysconf (_SC_CLK_TCK). (Consulte también los horarios (2)). Esto incluye el tiempo de invitado, cguest_time (tiempo dedicado a ejecutar un CPU virtual , vea abajo).

cstime% ld

Cantidad de tiempo que de este proceso esperado, los niños han sido programado en modo kernel, medida en ciclos de reloj (dividir por sysconf (_SC_CLK_TCK).

Ver proc(5) manpage para obtener detalles.

+0

¿Qué significa que el padre esté esperando los procesos hijos? ¿Esta técnica fallará si los procesos secundarios se bifurcan para ejecutarse en segundo plano? –

1

Puede que no sea el comando exacto. Pero puede hacer algo como a continuación para obtener el uso de CPU de varios procesos y agregarlo.

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

/proc/[pid]/STAT La información de estado acerca del proceso. Esto es utilizado por ps y hecho en forma legible por humanos.

Otra forma es usar cgroups y usar 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

2

Y, por supuesto, puede hacerlo en el hardcore vías usando el bueno de 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; 
} 

Compilar:

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

¡Disfrútalo!

0

Aquí hay una línea para calcular la CPU total para todos los procesos. Puede ajustarlo pasando el filtro de columna a la salida superior:

top -b -d 5 -n 2 | awk '$1 == "PID" {block_num++; next} block_num == 2 {sum += $9;} END {print sum}' 
Cuestiones relacionadas