2008-12-08 6 views
19

Je viens d'écrire la fonction C++ suivante pour déterminer par programme combien de RAM un système a installé. Cela fonctionne, mais il me semble qu'il devrait y avoir une façon plus simple de le faire. Quelqu'un peut-il me dire s'il me manque quelque chose?Comment déterminez-vous la quantité de RAM système 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; 
} 

Tout d'abord, j'utilise popen("head -n1 /proc/meminfo") pour obtenir la première ligne du fichier meminfo du système. La sortie de cette commande ressemble

MemTotal: 775280 kB

Une fois que j'ai que la production dans un istringstream, il est facile de tokenizer pour obtenir l'information que je veux. Ma question est, y a-t-il un moyen plus simple de lire dans la sortie de cette commande? Y at-il un appel de bibliothèque C++ standard à lire dans la quantité de RAM système?

Répondre

62

Sur Linux, vous pouvez utiliser la fonction sysinfo qui fixe des valeurs dans la structure suivante:

#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 vous voulez le faire en utilisant uniquement les fonctions C++ (je tiendrais à sysinfo), je vous recommande de prendre une approche C++ en utilisant std::ifstream et 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 fonctionne parfaitement. Je vous remercie. –

+0

vous pouvez vouloir fermer la poignée de fichier après avoir lu – segfault

+1

Sûrement les destructeurs le font déjà. –

0

Même top (à partir de procps) analyse /proc/meminfo, voir here.

4

Vous n'avez pas besoin d'utiliser popen(), vous pouvez simplement lire le fichier vous-même. En outre, si la première ligne n'est pas celle que vous cherchez, vous échouerez, car head -n1 lit uniquement la première ligne, puis quitte. Je ne sais pas pourquoi vous mélangez les E/S C et C++ comme ça; C'est tout à fait OK, mais vous devriez probablement choisir d'utiliser tout le C ou tout le C++. Je ferais probablement quelque chose comme ceci:

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 première ligne de/proc/meminfo était l'information que je recherchais. Je retourne en C++ après de nombreuses années, donc je n'ai pas encore une bonne idée du style C vs. C++, mais je travaille dessus. Merci. :) –

2

Reme mber/proc/meminfo est juste un fichier. Ouvrez le fichier, lisez la première ligne, fermez le fichier. Voila!

Questions connexes