Angle mort des performances : pourquoi votre processus ignore sa propre consommation ?
\n\nImaginez : vous avez développé une application complexe en C++, elle fonctionne mais commence à ralentir. Vous lancez top, htop ou le gestionnaire de tâches — et vous constatez que votre processus dévore 90% du CPU ou des gigaoctets de mémoire. Mais comment faire pour que le processus lui-même en preme conscience et, par exemple, réduise dynamiquement la charge ou vide son cache ?
Ce n'est pas qu'un exercice théorique. En production, sur des serveurs sans interface graphique, vous ne pouvez pas compter sur des outils externes. Il faut que le programme s'auto-surveille. C'est exactement ce que résout la question populaire sur Stack Overflow : "How to determine CPU and memory consumption from inside a process". Analysons-la avec des exemples concrets en C++.
\n\nLe dilemme multiplateforme : Linux vs Windows
\n\nLes systèmes d'exploitation donnent accès aux statistiques des processus de manière différente. Sous Linux, on utilise le système de fichiers virtuel /proc, tandis que Windows exploite l'API Win32. Nous allons créer une classe universelle fonctionnant sur les deux plateformes.
Les métriques principales que nous allons récupérer :
\n- \n
- Utilisation CPU (en pourcentage ou fraction de cœur) \n
- Mémoire physique (RSS) — la RAM réellement utilisée \n
- Mémoire virtuelle (VSZ) — l'espace d'adressage total \n
Lire le CPU sous Linux : la magie de /proc/self/stat
\n\nPour obtenir le temps CPU du processus, on lit le fichier /proc/self/stat. Il contient des dizaines de champs ; nous nous intéressons aux champs 13 à 16 (utime, stime, cutime, cstime) — le temps en ticks (jiffies). Pour convertir en pourcentage, il faut connaître la fréquence des ticks (sysconf(_SC_CLK_TCK)) et le temps total de fonctionnement du système.
#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 // Temps du processus\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 // Temps système\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\nCe code calcule le pourcentage CPU utilisé par le processus depuis le premier appel. Notez que nous prenons la différence entre deux mesures — c'est l'approche standard pour la précision.
\n\nMémoire sous Linux : RSS et VSZ
\n\nPour la mémoire, on lit /proc/self/status. Les lignes qui nous intéressent sont