2016-08-08 42 views
1

ich ein C-Programm, das das/proc // stat Verzeichnis analysiert die durchschnittliche CPU-Auslastung über einen Zeitraum von 5 Sekunden zu berechnen:C-Programm CPU-Auslastung für eine PID und alle seine Kinder zu bekommen

#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); 
} 

von dem, was ich auf die entsprechenden Felder in stat verstehen sind:

  • int utime;/** Benutzermodus jiffies **/

  • int stime;/** kernel modus jiffies **/

  • int schnittzeit;/** Benutzermodus jiffies mit Kindern **/

  • int cstime;/** Kernel-Modus jiffies mit Kindern **/

Für einen Prozess, das funktioniert gut, aber wenn ich einen Prozess haben, Gabeln oder multithreaded, diese bricht. Funktionieren die Indikatoren für "cutime" und "cstime" nur, wenn das übergeordnete Element auf die untergeordneten Prozesse wartet? Wie kann ich die Gesamtnutzung des Prozessbaums berechnen, der auf PID basiert?

+0

Warum nicht Ihre Fehler auf 'stderr' ausgeben? – Ascam

+0

@Ascam Ich sollte, ich denke, ich war nur zu diesem Zeitpunkt faul. Du hast Recht. – anthozep

+1

Wie auch immer, nur wenn Sie der Logik folgen, werden Sie nur Informationen über ** diese ** PID erhalten, da Sie eine PID verfolgen. Jeder Kindprozess ist ein ... ** Prozess **, Sie beziehen sich auf ihn mit seiner eigenen ID. Mein letzter Punkt ist: Ja, es scheint normal, dass Sie nur einige "warten" -Aktivität bekommen, Eltern zu beobachten. – Ascam

Antwort

1

Ja, das übergeordnete Element muss auf die CPU-Zeit der untergeordneten Elemente warten (siehe manuelle Eingabe für getrusagelink). Siehe auch this answer für weitere Details.

+0

Gibt es also eine Möglichkeit, den Prozessbaum von/proc zu bekommen? Wenn ja, könnte ich dies möglicherweise eine rekursive Lösung machen – anthozep

+0

Auf einigen Kernen, können Sie möglicherweise die Kinder von '/ proc/** pid **/task/** taskid **/children 'Datei [siehe Link] (https://lkml.org/lkml/2011/12/28/59). Andernfalls können Sie eine umgekehrte Suche von der übergeordneten PID aus durchführen. Die Eltern-PID wird in '/ proc/* pid */status' in der Zeile' PPid' aufgelistet. Sie können es mit folgender Shell versuchen: 'fgrep PPid/proc/[0-9] */status 2>/dev/null | fgrep $$ | Schneiden Sie -d/-f3' aus, das Unterprozesse Ihrer Shell auflisten soll ('$$'). Beachten Sie, dass der Grep/Cut selbst in dieser Liste angezeigt wird, aber diese Prozesse sind zu dem Zeitpunkt verschwunden, zu dem Ihre Eingabeaufforderung zurückkehrt. – Jerzy