2012-10-13 9 views
7

Chcę poznać wykorzystanie procesora przez proces i wszystkie procesy potomne, przez określony czas, w systemie Linux.Jak obliczyć wykorzystanie CPU procesu i wszystkich jego procesów podrzędnych w systemie Linux?

Aby być bardziej konkretne, tu jest mój use-case:

Jest to proces, który czeka na żądanie użytkownika w celu wykonania tych programów. Aby uruchomić programy, proces ten wywołuje procesy podrzędne (maksymalny limit 5 naraz) & każdy z tego procesu potomnego wykonuje 1 z tych nadesłanych programów (załóżmy, że użytkownik przesłał 15 programów jednocześnie). Tak więc, jeśli użytkownik prześle 15 programów, to każda z 3 partii po 5 procesów potomnych będzie działać. Procesy potomne są zabijane zaraz po zakończeniu wykonywania programu.

Chcę wiedzieć o% Wykorzystanie procesora dla procesu nadrzędnego i całego procesu potomnego podczas wykonywania tych 15 programów.

Czy istnieje prosty sposób, aby to zrobić, używając polecenia top lub innego? (Lub każde narzędzie, które powinienem dołączyć do procesu nadrzędnego).

Odpowiedz

8

Możesz znaleźć te informacje w /proc/PID/stat, gdzie PID jest identyfikatorem procesu twojego nadrzędnego procesu. Przyjmując, że proces macierzysty czeka na jej dzieci wówczas całkowite użycie CPU może być obliczona z utime, stime, cutime i cstime:

utime% lu

Ilość czasu że proces ten został zaplanowany w trybie użytkownika, zmierzony w tyknięciu zegara (dzielenie przez sysconf (_SC_CLK_TCK), który obejmuje czas gościa, guest_time (czas spędzony na uruchomieniu wirtualnego procesora, patrz poniżej), , tak aby pliki, które nie są świadome pola czasu gościa, nie tracą tego czasu z ich obliczeń.

stime% lu

Okres czasu, który to proces jest zaplanowane w trybie jądra mierzony w zegarze z kleszczami (dzielenie przez sysconf (_SC_CLK_TCK).

cutime% ld

Ilość czas, w którym proces ten był oczekiwany - dla dzieci został zaplanowany w trybie użytkownika, zmierzony w taktach zegara (podziel według sysconf (_SC_CLK_TCK). (Zobacz także czasy (2).) Obejmuje to czas gościa, cguest_time (czas spędzony na wirtualny procesor patrz poniżej).

cstime% ld

Okres czasu, który to proces na oczekiwanym dla dzieci były zaplanowane w trybie jądra, mierzony w zegarze z kleszczami (dzielenie przez sysconf (_SC_CLK_TCK).

Patrz proc(5) manpage Aby uzyskać szczegółowe informacje:

+0

Co to znaczy, że rodzic oczekuje na procesy potomne? Czy ta technika zawodzi, jeśli procesy potomne są rozwidlone i działają w tle? –

1

Może nie być dokładnym poleceniem, ale możesz zrobić coś takiego, jak poniżej, aby uzyskać użycie procesora w różnych procesach i dodać go.

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

/Proc/[PID]/STAT informacji o stanie procesu. To jest używane przez ps i wprowadzane do postaci czytelnej dla człowieka.

Innym sposobem jest użycie cgroups i użycie 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

I oczywiście można to zrobić w sposób, używając hardcore stare dobre 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; 
} 

kompilacji:

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

Ciesz się!

0

Oto jeden liniowiec do obliczenia całkowitego procesora dla wszystkich procesów. Możesz go dostosować, przekazując filtr kolumnowy do górnego wyjścia:

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