2008-12-08 12 views
19

Acabo de escribir la siguiente función C++ para determinar programáticamente cuánta RAM ha instalado un sistema. Funciona, pero me parece que debería haber una forma más simple de hacerlo. ¿Puede alguien decirme si me estoy perdiendo algo?¿Cómo se determina la cantidad de RAM del sistema Linux en C++?

getRAM() 
{ 
    FILE* stream = popen("head -n1 /proc/meminfo", "r"); 
    std::ostringstream output; 
    int bufsize = 128; 

    while(!feof(stream) && !ferror(stream)) 
    { 
     char buf[bufsize]; 
     int bytesRead = fread(buf, 1, bufsize, stream); 
     output.write(buf, bytesRead); 
    } 
    std::string result = output.str(); 

    std::string label, ram; 
    std::istringstream iss(result); 
    iss >> label; 
    iss >> ram; 

    return ram; 
} 

En primer lugar, estoy usando popen("head -n1 /proc/meminfo") para conseguir la primera línea del archivo meminfo del sistema. La salida de ese comando se parece

MemTotal: 775280 kB

Una vez que tengo que la producción en un istringstream, es fácil de tokenize que para llegar a la información que quiero. Mi pregunta es, ¿hay alguna manera más simple de leer en la salida de este comando? ¿Hay una llamada estándar de biblioteca C++ para leer en la cantidad de RAM del sistema?

Respuesta

62

En Linux, puede utilizar la función sysinfo que establece los valores de la siguiente estructura:

#include <sys/sysinfo.h> 

    int sysinfo(struct sysinfo *info); 

    struct sysinfo { 
     long uptime;    /* Seconds since boot */ 
     unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ 
     unsigned long totalram; /* Total usable main memory size */ 
     unsigned long freeram; /* Available memory size */ 
     unsigned long sharedram; /* Amount of shared memory */ 
     unsigned long bufferram; /* Memory used by buffers */ 
     unsigned long totalswap; /* Total swap space size */ 
     unsigned long freeswap; /* swap space still available */ 
     unsigned short procs; /* Number of current processes */ 
     unsigned long totalhigh; /* Total high memory size */ 
     unsigned long freehigh; /* Available high memory size */ 
     unsigned int mem_unit; /* Memory unit size in bytes */ 
     char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding for libc5 */ 
    }; 

Si desea hacerlo exclusivamente mediante funciones de C++ (que se pegaba a sysinfo), recomiendo tomar un enfoque C++ utilizando std::ifstream y std::string:

unsigned long get_mem_total() { 
    std::string token; 
    std::ifstream file("/proc/meminfo"); 
    while(file >> token) { 
     if(token == "MemTotal:") { 
      unsigned long mem; 
      if(file >> mem) { 
       return mem; 
      } else { 
       return 0;  
      } 
     } 
     // ignore rest of the line 
     file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
    } 
    return 0; // nothing found 
} 
+0

sysinfo funciona perfectamente. Gracias. –

+0

es posible que desee cerrar el identificador del archivo después de leer – segfault

+1

Seguramente los destructores ya lo hacen. –

0

Even top (de procps) analiza /proc/meminfo, vea here.

4

No es necesario utilizar popen(), puede leer el archivo usted mismo. Además, si la primera línea no es lo que estás buscando, fallarás, ya que head -n1 solo lee la primera línea y luego sale. No estoy seguro de por qué estás mezclando C y C++ I/O así; está perfectamente bien, pero probablemente deberías optar por usar C o C++. Probablemente lo haría algo como esto:

int GetRamInKB(void) 
{ 
    FILE *meminfo = fopen("/proc/meminfo", "r"); 
    if(meminfo == NULL) 
     ... // handle error 

    char line[256]; 
    while(fgets(line, sizeof(line), meminfo)) 
    { 
     int ram; 
     if(sscanf(line, "MemTotal: %d kB", &ram) == 1) 
     { 
      fclose(meminfo); 
      return ram; 
     } 
    } 

    // If we got here, then we couldn't find the proper line in the meminfo file: 
    // do something appropriate like return an error code, throw an exception, etc. 
    fclose(meminfo); 
    return -1; 
} 
+0

La primera línea tenía/proc/meminfo era la información que estaba buscando. Volveré a C++ después de muchos años, así que todavía no tengo un buen sentido del estilo C vs. C++, pero estoy trabajando en ello. Gracias. :) –

2

Reme mber/proc/meminfo es solo un archivo. Abra el archivo, lea la primera línea, cierre el archivo. Voilá!

Cuestiones relacionadas