Cómo medir CPU y memoria desde dentro del proceso en C++: guía completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Zona ciega de rendimiento: ¿por qué su proceso no sabe cuánto consume?

\n\n

Imagine: ha escrito una aplicación compleja en C++, funciona, pero empieza a ralentizarse. Ejecuta top, htop o el administrador de tareas — y ve que su proceso consume el 90% de CPU o gigabytes de memoria. Pero, ¿cómo hacer que el propio proceso tome conciencia de esto y, por ejemplo, reduzca dinámicamente la carga o libere la caché?

\n\n

Esto no es solo un interés académico. En un entorno de producción, en servidores sin GUI, no puede depender de utilidades externas. Es necesario que el programa se supervise a sí mismo. Precisamente este problema resuelve la popular pregunta en Stack Overflow: "How to determine CPU and memory consumption from inside a process". Analicémosla con ejemplos reales en C++.

\n\n

El dilema multiplataforma: Linux vs Windows

\n\n

Los sistemas operativos proporcionan acceso a las estadísticas de procesos de diferentes maneras. Bajo el capó de Linux se encuentra el sistema de archivos virtual /proc, mientras que Windows utiliza la API Win32. Escribiremos una clase universal que funcione en ambas plataformas.

\n\n

Las métricas principales que obtendremos:

\n
    \n
  • Uso de CPU (en porcentaje o fracciones de núcleo)
  • \n
  • Memoria física (RSS) — RAM realmente ocupada
  • \n
  • Memoria virtual (VSZ) — volumen total del espacio de direcciones
  • \n
\n\n

Lectura de CPU en Linux: la magia de /proc/self/stat

\n\n

Para obtener el tiempo de CPU del proceso, leemos el archivo /proc/self/stat. Contiene decenas de campos, nos interesan los campos 13-16 (utime, stime, cutime, cstime) — tiempo en ticks (jiffies). Para convertir a porcentaje, necesitamos conocer la frecuencia de ticks (sysconf(_SC_CLK_TCK)) y el tiempo total de funcionamiento del sistema.

\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    // Tiempo del proceso\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    // Tiempo del sistema\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

Este código calcula el porcentaje de CPU ocupado por el proceso desde la primera llamada. Tenga en cuenta: tomamos la diferencia entre dos mediciones — este es el enfoque estándar para la precisión.

\n\n

Memoria en Linux: RSS y VSZ

\n\n

Para la memoria, leemos /proc/self/status. Nos interesan las líneas

Blogs

Book Recommendations