Domanda

Ho appena scritto la seguente funzione C ++ per determinare programmaticamente quanta RAM ha installato un sistema. Funziona, ma mi sembra che ci dovrebbe essere un modo più semplice per farlo. Qualcuno può dirmi se mi manca qualcosa?

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;
}

In primo luogo, sto usando popen("head -n1 /proc/meminfo") per ottenere la prima riga del file meminfo dal sistema. L'output di quel comando appare come

  

MemTotal: 775280 kB

Una volta ottenuto quell'output in istringstream, è semplice tokenizzare per ottenere le informazioni che desidero. La mia domanda è: c'è un modo più semplice di leggere nell'output di questo comando? Esiste una chiamata alla libreria C ++ standard per leggere la quantità di RAM di sistema?

È stato utile?

Soluzione

Su Linux, è possibile utilizzare la funzione sysinfo che imposta i valori nella seguente struttura:

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

Se vuoi farlo usando solo le funzioni di C ++ (mi atterrerei a std::ifstream), ti consiglio di adottare un approccio C ++ usando std::string e <=>:

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
}

Altri suggerimenti

Non è necessario utilizzare popen(), puoi semplicemente leggere il file da solo. Inoltre, se la prima riga non è quella che stai cercando, fallirai, poiché head -n1 legge solo la prima riga e quindi esce. Non sono sicuro del perché stai combinando I / O C e C ++ in quel modo; è perfettamente OK, ma probabilmente dovresti scegliere di andare in C o C ++. Probabilmente farei qualcosa del genere:

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;
}

Ricorda / proc / meminfo è solo un file. Apri il file, leggi la prima riga, chiudi il file. Voil # 225 &;

Anche top (da procps) analizza /proc/meminfo, vedi qui .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top