2008-12-08 10 views
19

Ich habe gerade die folgende C++ - Funktion geschrieben, um programmatisch zu ermitteln, wie viel RAM ein System installiert hat. Es funktioniert, aber es scheint mir, dass es einen einfacheren Weg dafür geben sollte. Kann mir jemand sagen, ob ich etwas verpasse?Wie bestimmen Sie die Menge an Linux-System-RAM in 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; 
} 

Erstens, ich bin mit popen("head -n1 /proc/meminfo") die ersten Zeile der meminfo Datei aus dem System zu erhalten. Die Ausgabe dieses Befehls sieht aus wie

MemTotal: 775.280 kB

Sobald ich diese Ausgabe in einem istringstream haben, ist es einfach, es tokenize auf die Informationen zu bekommen was ich will. Meine Frage ist, gibt es eine einfachere Möglichkeit, die Ausgabe dieses Befehls einzulesen? Gibt es einen Standard-C++ - Bibliotheksaufruf zum Einlesen des System-RAM?

Antwort

62

Unter Linux können Sie die Funktion sysinfo verwenden, die Werte in der folgenden Struktur setzt:

#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 */ 
    }; 

Wenn Sie es nur mit den Funktionen tun wollen von C++ (i würde sysinfo Stick), empfehle ich einen C++ Ansatz mit std::ifstream und 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 funktioniert perfekt. Vielen Dank. –

+0

Sie möchten vielleicht die Datei Handle nach dem Lesen – segfault

+1

schließen Sicherlich tun die Destruktoren das schon. –

0

Sogar top (von procps) analysiert /proc/meminfo, siehe here.

4

Sie müssen popen() nicht verwenden, Sie können die Datei einfach selbst lesen. Auch wenn die erste Zeile nicht das ist, was Sie suchen, werden Sie scheitern, da head -n1 nur die erste Zeile liest und dann beendet. Ich bin mir nicht sicher, warum Sie C und C++ I/O so mischen; es ist vollkommen in Ordnung, aber Sie sollten wahrscheinlich entscheiden, alle C oder alle C++ zu gehen. Ich würde tun es wahrscheinlich so etwas wie dieses:

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

Die erste Zeile von/proc/meminfo war die Information, die ich suchte. Ich kehre nach vielen Jahren nach C++ zurück, daher habe ich noch kein gutes Gefühl für den C- und C++ - Stil, aber ich arbeite daran. Vielen Dank. :) –

2

Reme mber/proc/meminfo ist nur eine Datei. Öffnen Sie die Datei, lesen Sie die erste Zeile, schließen Sie die Datei. Voilá!