Wie man CPU und Arbeitsspeicher von innerhalb eines C++-Prozesses misst: Vollständiger Leitfaden

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Blinder Fleck der Leistung: Warum Ihr Prozess nicht weiß, wie viel er verbraucht?

\n\n

Stellen Sie sich vor: Sie haben eine komplexe Anwendung in C++ geschrieben, sie läuft, beginnt aber zu ruckeln. Sie starten top, htop oder den Task-Manager – und sehen, dass Ihr Prozess 90% CPU oder Gigabytes an Arbeitsspeicher frisst. Aber wie bringen Sie den Prozess dazu, dies selbst zu erkennen und z. B. dynamisch die Last zu reduzieren oder den Cache zu leeren?

\n\n

Dies ist nicht nur akademisches Interesse. In einer Produktionsumgebung auf Servern ohne GUI können Sie sich nicht auf externe Tools verlassen. Das Programm muss sich selbst überwachen. Genau diese Aufgabe löst die beliebte Frage auf Stack Overflow: "How to determine CPU and memory consumption from inside a process". Lassen Sie uns dies anhand praktischer Beispiele in C++ analysieren.

\n\n

Plattformübergreifendes Dilemma: Linux vs Windows

\n\n

Betriebssysteme bieten unterschiedliche Zugriffe auf Prozessstatistiken. Unter der Haube von Linux liegt das virtuelle Dateisystem /proc, während Windows die Win32-API verwendet. Wir schreiben eine universelle Klasse, die auf beiden Plattformen funktioniert.

\n\n

Die wichtigsten Metriken, die wir ermitteln werden:

\n
    \n
  • CPU-Auslastung (in Prozent oder Anteilen eines Kerns)
  • \n
  • Physikalischer Arbeitsspeicher (RSS) – tatsächlich belegter RAM
  • \n
  • Virtueller Arbeitsspeicher (VSZ) – gesamter Adressraum
  • \n
\n\n

CPU unter Linux auslesen: Die Magie von /proc/self/stat

\n\n

Um die CPU-Zeit des Prozesses zu erhalten, lesen wir die Datei /proc/self/stat. Sie enthält dutzende Felder, uns interessieren die Felder 13-16 (utime, stime, cutime, cstime) – die Zeit in Ticks (Jiffies). Um dies in Prozent umzurechnen, benötigen wir die Tick-Frequenz (sysconf(_SC_CLK_TCK)) und die gesamte Systemlaufzeit.

\n\n
#ifdef __linux__\n#include <unistd.h>\n#include <fstream>\n#include <sstream>\n#include <string>\n#include <vector>\n\ndouble getCpuUsageLinux() {\n    static unsigned long long prevTotal = 0, prevIdle = 0;\n    static double prevProcessTicks = 0;\n    static bool first = true;\n\n    // Prozesszeit\n    std::ifstream procStat("/proc/self/stat");\n    std::string line;\n    std::getline(procStat, line);\n    std::istringstream iss(line);\n    std::vector<std::string> fields;\n    std::string field;\n    while (iss >> field) fields.push_back(field);\n\n    unsigned long utime = std::stoul(fields[13]);\n    unsigned long stime = std::stoul(fields[14]);\n    unsigned long cutime = std::stoul(fields[15]);\n    unsigned long cstime = std::stoul(fields[16]);\n    double processTicks = utime + stime + cutime + cstime;\n\n    // Systemzeit\n    std::ifstream statFile("/proc/stat");\n    std::getline(statFile, line);\n    statFile.close();\n    std::istringstream iss2(line);\n    std::string cpuLabel;\n    iss2 >> cpuLabel;\n    unsigned long long user, nice, system, idle, iowait, irq, softirq, steal;\n    iss2 >> user >> nice >> system >> idle >> iowait >> irq >> softirq >> steal;\n    unsigned long long total = user + nice + system + idle + iowait + irq + softirq + steal;\n\n    if (first) {\n        prevTotal = total;\n        prevIdle = idle;\n        prevProcessTicks = processTicks;\n        first = false;\n        return 0.0;\n    }\n\n    unsigned long long totalDelta = total - prevTotal;\n    double processDelta = processTicks - prevProcessTicks;\n    double cpuPercent = (processDelta / totalDelta) * 100.0;\n\n    prevTotal = total;\n    prevIdle = idle;\n    prevProcessTicks = processTicks;\n\n    return cpuPercent;\n}\n#endif\n
\n\n

Dieser Code berechnet den CPU-Prozentsatz, den der Prozess seit dem ersten Aufruf belegt hat. Beachten Sie: Wir bilden die Differenz zwischen zwei Messungen – dies ist der Standardansatz für Genauigkeit.

\n\n

Arbeitsspeicher unter Linux: RSS und VSZ

\n\n

Für den Arbeitsspeicher lesen wir /proc/self/status. Uns interessieren die Zeilen

Blogs

Buchempfehlungen